diff --git a/Dockerfile b/Dockerfile index cd7f430b..a8afbc84 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,8 +7,8 @@ COPY package.json pnpm-lock.yaml .npmrc binding.gyp ./ COPY addon ./addon COPY patches ./patches -RUN echo "https://dl-cdn.alpinelinux.org/alpine/v3.18/main" > /etc/apk/repositories \ - && echo "https://dl-cdn.alpinelinux.org/alpine/v3.18/community" >> /etc/apk/repositories \ +RUN echo "https://dl-cdn.alpinelinux.org/alpine/v3.19/main" > /etc/apk/repositories \ + && echo "https://dl-cdn.alpinelinux.org/alpine/v3.19/community" >> /etc/apk/repositories \ && apk update && apk upgrade \ && apk add --no-cache tzdata \ && echo "Asia/Shanghai" > /etc/timezone \ @@ -55,7 +55,7 @@ COPY --from=dependencies /etc/timezone /etc/timezone # yt-dlp # 在 Alpine Linux 中,`pip` 不是默认与 `python3` 一起安装的。要在 Alpine Linux 上安装 `pip`,您需要安装 `py3-pip` 包。 RUN apk add --no-cache ffmpeg python3 py3-pip vips-dev \ - && pip install --no-cache-dir yt-dlp + && pip install --break-system-packages --no-cache-dir yt-dlp USER node diff --git a/addon/TinyEXIF/TinyEXIF.cpp b/addon/TinyEXIF/TinyEXIF.cpp deleted file mode 100644 index 78dd9207..00000000 --- a/addon/TinyEXIF/TinyEXIF.cpp +++ /dev/null @@ -1,1317 +0,0 @@ -/* - TinyEXIF.cpp -- A simple ISO C++ library to parse basic EXIF and XMP - information from a JPEG file. - - Copyright (c) 2015-2017 Seacave - cdc.seacave@gmail.com - All rights reserved. - - Based on the easyexif library (2013 version) - https://github.com/mayanklahiri/easyexif - of Mayank Lahiri (mlahiri@gmail.com). - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "TinyEXIF.h" - -#ifndef TINYEXIF_NO_XMP_SUPPORT -#include "../tinyxml2/tinyxml2.h" -#endif // TINYEXIF_NO_XMP_SUPPORT - -#include -#include -#include -#include -#include -#include -#include - -#ifdef _MSC_VER -namespace { - int strcasecmp(const char* a, const char* b) { - return _stricmp(a, b); - } -} -#else -#include -#endif - - -namespace Tools { - - // search string inside a string, case sensitive - static const char* strrnstr(const char* haystack, const char* needle, size_t len) { - const size_t needle_len(strlen(needle)); - if (0 == needle_len) - return haystack; - if (len <= needle_len) - return NULL; - for (size_t i=len-needle_len; i-- > 0; ) { - if (haystack[0] == needle[0] && - 0 == strncmp(haystack, needle, needle_len)) - return haystack; - haystack++; - } - return NULL; - } - - // split an input string with a delimiter and fill a string vector - static void strSplit(const std::string& str, char delim, std::vector& values) { - values.clear(); - std::string::size_type start(0), end(0); - while (end != std::string::npos) { - end = str.find(delim, start); - values.emplace_back(str.substr(start, end-start)); - start = end + 1; - } - } - - // make sure the given degrees value is between -180 and 180 - static double NormD180(double d) { - return (d = fmod(d+180.0, 360.0)) < 0 ? d+180.0 : d-180.0; - } - -} // namespace Tools - - -namespace TinyEXIF { - -enum JPEG_MARKERS { - JM_START = 0xFF, - JM_SOF0 = 0xC0, - JM_SOF1 = 0xC1, - JM_SOF2 = 0xC2, - JM_SOF3 = 0xC3, - JM_DHT = 0xC4, - JM_SOF5 = 0xC5, - JM_SOF6 = 0xC6, - JM_SOF7 = 0xC7, - JM_JPG = 0xC8, - JM_SOF9 = 0xC9, - JM_SOF10 = 0xCA, - JM_SOF11 = 0xCB, - JM_DAC = 0xCC, - JM_SOF13 = 0xCD, - JM_SOF14 = 0xCE, - JM_SOF15 = 0xCF, - JM_RST0 = 0xD0, - JM_RST1 = 0xD1, - JM_RST2 = 0xD2, - JM_RST3 = 0xD3, - JM_RST4 = 0xD4, - JM_RST5 = 0xD5, - JM_RST6 = 0xD6, - JM_RST7 = 0xD7, - JM_SOI = 0xD8, - JM_EOI = 0xD9, - JM_SOS = 0xDA, - JM_DQT = 0xDB, - JM_DNL = 0xDC, - JM_DRI = 0xDD, - JM_DHP = 0xDE, - JM_EXP = 0xDF, - JM_APP0 = 0xE0, - JM_APP1 = 0xE1, // EXIF and XMP - JM_APP2 = 0xE2, - JM_APP3 = 0xE3, - JM_APP4 = 0xE4, - JM_APP5 = 0xE5, - JM_APP6 = 0xE6, - JM_APP7 = 0xE7, - JM_APP8 = 0xE8, - JM_APP9 = 0xE9, - JM_APP10 = 0xEA, - JM_APP11 = 0xEB, - JM_APP12 = 0xEC, - JM_APP13 = 0xED, // IPTC - JM_APP14 = 0xEE, - JM_APP15 = 0xEF, - JM_JPG0 = 0xF0, - JM_JPG1 = 0xF1, - JM_JPG2 = 0xF2, - JM_JPG3 = 0xF3, - JM_JPG4 = 0xF4, - JM_JPG5 = 0xF5, - JM_JPG6 = 0xF6, - JM_JPG7 = 0xF7, - JM_JPG8 = 0xF8, - JM_JPG9 = 0xF9, - JM_JPG10 = 0xFA, - JM_JPG11 = 0xFB, - JM_JPG12 = 0xFC, - JM_JPG13 = 0xFD, - JM_COM = 0xFE -}; - - -// Parser helper -class EntryParser { -private: - const uint8_t* buf; - const unsigned len; - const unsigned tiff_header_start; - const bool alignIntel; // byte alignment (defined in EXIF header) - unsigned offs; // current offset into buffer - uint16_t tag, format; - uint32_t length; - -public: - EntryParser(const uint8_t* _buf, unsigned _len, unsigned _tiff_header_start, bool _alignIntel) - : buf(_buf), len(_len), tiff_header_start(_tiff_header_start), alignIntel(_alignIntel), offs(0) {} - - void Init(unsigned _offs) { - offs = _offs - 12; - } - - void ParseTag() { - offs += 12; - tag = parse16(buf + offs, alignIntel); - format = parse16(buf + offs + 2, alignIntel); - length = parse32(buf + offs + 4, alignIntel); - } - - const uint8_t* GetBuffer() const { return buf; } - unsigned GetOffset() const { return offs; } - bool IsIntelAligned() const { return alignIntel; } - - uint16_t GetTag() const { return tag; } - uint32_t GetLength() const { return length; } - uint32_t GetData() const { return parse32(buf + offs + 8, alignIntel); } - uint32_t GetSubIFD() const { return tiff_header_start + GetData(); } - - bool IsShort() const { return format == 3; } - bool IsLong() const { return format == 4; } - bool IsRational() const { return format == 5 || format == 10; } - bool IsSRational() const { return format == 10; } - bool IsFloat() const { return format == 11; } - bool IsUndefined() const { return format == 7; } - - std::string FetchString() const { - return parseString(buf, length, GetData(), tiff_header_start, len, alignIntel); - } - bool Fetch(std::string& val) const { - if (format != 2 || length == 0) - return false; - val = FetchString(); - return true; - } - bool Fetch(uint8_t& val) const { - if ((format != 1 && format != 2 && format != 6) || length == 0) - return false; - val = parse8(buf + offs + 8); - return true; - } - bool Fetch(uint16_t& val) const { - if (!IsShort() || length == 0) - return false; - val = parse16(buf + offs + 8, alignIntel); - return true; - } - bool Fetch(uint16_t& val, uint32_t idx) const { - if (!IsShort() || length <= idx) - return false; - val = parse16(buf + GetSubIFD() + idx*2, alignIntel); - return true; - } - bool Fetch(uint32_t& val) const { - if (!IsLong() || length == 0) - return false; - val = parse32(buf + offs + 8, alignIntel); - return true; - } - bool Fetch(float& val) const { - if (!IsFloat() || length == 0) - return false; - val = parseFloat(buf + offs + 8, alignIntel); - return true; - } - bool Fetch(double& val) const { - if (!IsRational() || length == 0) - return false; - val = parseRational(buf + GetSubIFD(), alignIntel, IsSRational()); - return true; - } - bool Fetch(double& val, uint32_t idx) const { - if (!IsRational() || length <= idx) - return false; - val = parseRational(buf + GetSubIFD() + idx*8, alignIntel, IsSRational()); - return true; - } - - bool FetchFloat(double& val) const { - float _val; - if (!Fetch(_val)) - return false; - val = _val; - return true; - } - -public: - static uint8_t parse8(const uint8_t* buf) { - return buf[0]; - } - static uint16_t parse16(const uint8_t* buf, bool intel) { - if (intel) - return ((uint16_t)buf[1]<<8) | buf[0]; - return ((uint16_t)buf[0]<<8) | buf[1]; - } - static uint32_t parse32(const uint8_t* buf, bool intel) { - if (intel) - return ((uint32_t)buf[3]<<24) | - ((uint32_t)buf[2]<<16) | - ((uint32_t)buf[1]<<8) | - buf[0]; - return ((uint32_t)buf[0]<<24) | - ((uint32_t)buf[1]<<16) | - ((uint32_t)buf[2]<<8) | - buf[3]; - } - static float parseFloat(const uint8_t* buf, bool intel) { - union { - uint32_t i; - float f; - } i2f; - i2f.i = parse32(buf, intel); - return i2f.f; - } - static double parseRational(const uint8_t* buf, bool intel, bool isSigned) { - const uint32_t denominator = parse32(buf+4, intel); - if (denominator == 0) - return 0.0; - const uint32_t numerator = parse32(buf, intel); - return isSigned ? - (double)(int32_t)numerator/(double)(int32_t)denominator : - (double)numerator/(double)denominator; - } - static std::string parseString(const uint8_t* buf, - unsigned num_components, - unsigned data, - unsigned base, - unsigned len, - bool intel) - { - std::string value; - if (num_components <= 4) { - value.resize(num_components); - char j = intel ? 0 : 24; - char j_m = intel ? -8 : 8; - for (unsigned i=0; i> j) & 0xff; - if (value[num_components-1] == '\0') - value.resize(num_components-1); - } else - if (base+data+num_components <= len) { - const char* const sz((const char*)buf+base+data); - unsigned num(0); - while (num < num_components && sz[num] != '\0') - ++num; - while (num && sz[num-1] == ' ') - --num; - value.assign(sz, num); - } - return value; - } -}; - - -// Constructors -EXIFInfo::EXIFInfo() : Fields(FIELD_NA) { -} -EXIFInfo::EXIFInfo(EXIFStream& stream) { - parseFrom(stream); -} -EXIFInfo::EXIFInfo(std::istream& stream) { - parseFrom(stream); -} -EXIFInfo::EXIFInfo(const uint8_t* data, unsigned length) { - parseFrom(data, length); -} - - -// Parse tag as Image IFD -void EXIFInfo::parseIFDImage(EntryParser& parser, unsigned& exif_sub_ifd_offset, unsigned& gps_sub_ifd_offset) { - switch (parser.GetTag()) { - case 0x0102: - // Bits per sample - parser.Fetch(BitsPerSample); - break; - - case 0x010e: - // Image description - parser.Fetch(ImageDescription); - break; - - case 0x010f: - // Camera maker - parser.Fetch(Make); - break; - - case 0x0110: - // Camera model - parser.Fetch(Model); - break; - - case 0x0112: - // Orientation of image - parser.Fetch(Orientation); - break; - - case 0x011a: - // XResolution - parser.Fetch(XResolution); - break; - - case 0x011b: - // YResolution - parser.Fetch(YResolution); - break; - - case 0x0128: - // Resolution Unit - parser.Fetch(ResolutionUnit); - break; - - case 0x0131: - // Software used for image - parser.Fetch(Software); - break; - - case 0x0132: - // EXIF/TIFF date/time of image modification - parser.Fetch(DateTime); - break; - - case 0x1001: - // Original Image width - if (!parser.Fetch(RelatedImageWidth)) { - uint16_t _RelatedImageWidth; - if (parser.Fetch(_RelatedImageWidth)) - RelatedImageWidth = _RelatedImageWidth; - } - break; - - case 0x1002: - // Original Image height - if (!parser.Fetch(RelatedImageHeight)) { - uint16_t _RelatedImageHeight; - if (parser.Fetch(_RelatedImageHeight)) - RelatedImageHeight = _RelatedImageHeight; - } - break; - - case 0x8298: - // Copyright information - parser.Fetch(Copyright); - break; - - case 0x8769: - // EXIF SubIFD offset - exif_sub_ifd_offset = parser.GetSubIFD(); - break; - - case 0x8825: - // GPS IFS offset - gps_sub_ifd_offset = parser.GetSubIFD(); - break; - - default: - // Try to parse as EXIF tag, as some images store them in here - parseIFDExif(parser); - break; - } -} - -// Parse tag as Exif IFD -void EXIFInfo::parseIFDExif(EntryParser& parser) { - switch (parser.GetTag()) { - case 0x02bc: -#ifndef TINYEXIF_NO_XMP_SUPPORT - // XMP Metadata (Adobe technote 9-14-02) - if (parser.IsUndefined()) { - const std::string strXML(parser.FetchString()); - parseFromXMPSegmentXML(strXML.c_str(), (unsigned)strXML.length()); - } -#endif // TINYEXIF_NO_XMP_SUPPORT - break; - - case 0x829a: - // Exposure time in seconds - parser.Fetch(ExposureTime); - break; - - case 0x829d: - // FNumber - parser.Fetch(FNumber); - break; - - case 0x8822: - // Exposure Program - parser.Fetch(ExposureProgram); - break; - - case 0x8827: - // ISO Speed Rating - parser.Fetch(ISOSpeedRatings); - break; - - case 0x9003: - // Original date and time - parser.Fetch(DateTimeOriginal); - break; - - case 0x9004: - // Digitization date and time - parser.Fetch(DateTimeDigitized); - break; - - case 0x9201: - // Shutter speed value - parser.Fetch(ShutterSpeedValue); - ShutterSpeedValue = 1.0/exp(ShutterSpeedValue*log(2)); - break; - - case 0x9202: - // Aperture value - parser.Fetch(ApertureValue); - ApertureValue = exp(ApertureValue*log(2)*0.5); - break; - - case 0x9203: - // Brightness value - parser.Fetch(BrightnessValue); - break; - - case 0x9204: - // Exposure bias value - parser.Fetch(ExposureBiasValue); - break; - - case 0x9206: - // Subject distance - parser.Fetch(SubjectDistance); - break; - - case 0x9207: - // Metering mode - parser.Fetch(MeteringMode); - break; - - case 0x9208: - // Light source - parser.Fetch(LightSource); - break; - - case 0x9209: - // Flash info - parser.Fetch(Flash); - break; - - case 0x920a: - // Focal length - parser.Fetch(FocalLength); - break; - - case 0x9214: - // Subject area - if (parser.IsShort() && parser.GetLength() > 1) { - SubjectArea.resize(parser.GetLength()); - for (uint32_t i=0; i parser.GetLength()) - return; - parser.Init(off+2); - parser.ParseTag(); - --num_entries; - std::string maker; - if (parser.GetTag() == 1 && parser.Fetch(maker)) { - if (0 == strcasecmp(maker.c_str(), "DJI")) { - while (--num_entries >= 0) { - parser.ParseTag(); - switch (parser.GetTag()) { - case 3: - // SpeedX - parser.FetchFloat(GeoLocation.SpeedX); - break; - - case 4: - // SpeedY - parser.FetchFloat(GeoLocation.SpeedY); - break; - - case 5: - // SpeedZ - parser.FetchFloat(GeoLocation.SpeedZ); - break; - - case 9: - // Camera Pitch - parser.FetchFloat(GeoLocation.PitchDegree); - break; - - case 10: - // Camera Yaw - parser.FetchFloat(GeoLocation.YawDegree); - break; - - case 11: - // Camera Roll - parser.FetchFloat(GeoLocation.RollDegree); - break; - } - } - } - } - parser.Init(startOff+12); -} - -// Parse tag as GPS IFD -void EXIFInfo::parseIFDGPS(EntryParser& parser) { - switch (parser.GetTag()) { - case 1: - // GPS north or south - parser.Fetch(GeoLocation.LatComponents.direction); - break; - - case 2: - // GPS latitude - if (parser.IsRational() && parser.GetLength() == 3) { - parser.Fetch(GeoLocation.LatComponents.degrees, 0); - parser.Fetch(GeoLocation.LatComponents.minutes, 1); - parser.Fetch(GeoLocation.LatComponents.seconds, 2); - } - break; - - case 3: - // GPS east or west - parser.Fetch(GeoLocation.LonComponents.direction); - break; - - case 4: - // GPS longitude - if (parser.IsRational() && parser.GetLength() == 3) { - parser.Fetch(GeoLocation.LonComponents.degrees, 0); - parser.Fetch(GeoLocation.LonComponents.minutes, 1); - parser.Fetch(GeoLocation.LonComponents.seconds, 2); - } - break; - - case 5: - // GPS altitude reference (below or above sea level) - parser.Fetch((uint8_t&)GeoLocation.AltitudeRef); - break; - - case 6: - // GPS altitude - parser.Fetch(GeoLocation.Altitude); - break; - - case 7: - // GPS timestamp - if (parser.IsRational() && parser.GetLength() == 3) { - double h,m,s; - parser.Fetch(h, 0); - parser.Fetch(m, 1); - parser.Fetch(s, 2); - char buffer[256]; - snprintf(buffer, 256, "%g %g %g", h, m, s); - GeoLocation.GPSTimeStamp = buffer; - } - break; - - case 11: - // Indicates the GPS DOP (data degree of precision) - parser.Fetch(GeoLocation.GPSDOP); - break; - - case 18: - // GPS geodetic survey data - parser.Fetch(GeoLocation.GPSMapDatum); - break; - - case 29: - // GPS date-stamp - parser.Fetch(GeoLocation.GPSDateStamp); - break; - - case 30: - // GPS differential indicates whether differential correction is applied to the GPS receiver - parser.Fetch(GeoLocation.GPSDifferential); - break; - } -} - - -// -// Locates the JM_APP1 segment and parses it using -// parseFromEXIFSegment() or parseFromXMPSegment() -// -int EXIFInfo::parseFrom(EXIFStream& stream) { - clear(); - if (!stream.IsValid()) - return PARSE_INVALID_JPEG; - - // Sanity check: all JPEG files start with 0xFFD8 and end with 0xFFD9 - // This check also ensures that the user has supplied a correct value for len. - const uint8_t* buf(stream.GetBuffer(2)); - if (buf == NULL || buf[0] != JM_START || buf[1] != JM_SOI) - return PARSE_INVALID_JPEG; - - // Scan for JM_APP1 header (bytes 0xFF 0xE1) and parse its length. - // Exit if both EXIF and XMP sections were parsed. - struct APP1S { - uint32_t& val; - inline APP1S(uint32_t& v) : val(v) {} - inline operator uint32_t () const { return val; } - inline operator uint32_t& () { return val; } - inline int operator () (int code=PARSE_ABSENT_DATA) const { return val&FIELD_ALL ? (int)PARSE_SUCCESS : code; } - } app1s(Fields); - while ((buf=stream.GetBuffer(2)) != NULL) { - // find next marker; - // in cases of markers appended after the compressed data, - // optional JM_START fill bytes may precede the marker - if (*buf++ != JM_START) - break; - uint8_t marker; - while ((marker=buf[0]) == JM_START && (buf=stream.GetBuffer(1)) != NULL); - // select marker - uint16_t sectionLength; - switch (marker) { - case 0x00: - case 0x01: - case JM_START: - case JM_RST0: - case JM_RST1: - case JM_RST2: - case JM_RST3: - case JM_RST4: - case JM_RST5: - case JM_RST6: - case JM_RST7: - case JM_SOI: - break; - case JM_SOS: // start of stream: and we're done - case JM_EOI: // no data? not good - return app1s(); - case JM_APP1: - if ((buf=stream.GetBuffer(2)) == NULL) - return app1s(PARSE_INVALID_JPEG); - sectionLength = EntryParser::parse16(buf, false); - if (sectionLength <= 2 || (buf=stream.GetBuffer(sectionLength-=2)) == NULL) - return app1s(PARSE_INVALID_JPEG); - switch (int ret=parseFromEXIFSegment(buf, sectionLength)) { - case PARSE_ABSENT_DATA: -#ifndef TINYEXIF_NO_XMP_SUPPORT - switch (ret=parseFromXMPSegment(buf, sectionLength)) { - case PARSE_ABSENT_DATA: - break; - case PARSE_SUCCESS: - if ((app1s|=FIELD_XMP) == FIELD_ALL) - return PARSE_SUCCESS; - break; - default: - return app1s(ret); // some error - } -#endif // TINYEXIF_NO_XMP_SUPPORT - break; - case PARSE_SUCCESS: - if ((app1s|=FIELD_EXIF) == FIELD_ALL) - return PARSE_SUCCESS; - break; - default: - return app1s(ret); // some error - } - break; - default: - // skip the section - if ((buf=stream.GetBuffer(2)) == NULL || - (sectionLength=EntryParser::parse16(buf, false)) <= 2 || - !stream.SkipBuffer(sectionLength-2)) - return app1s(PARSE_INVALID_JPEG); - } - } - return app1s(); -} - - -int EXIFInfo::parseFrom(std::istream& stream) { - class EXIFStdStream : public EXIFStream { - public: - EXIFStdStream(std::istream& stream) - : stream(stream) { - // Would be nice to assert here that the stream was opened in binary mode, but - // apparently that's not possible: https://stackoverflow.com/a/224259/19254 - } - bool IsValid() const override { - return !!stream; - } - const uint8_t* GetBuffer(unsigned desiredLength) override { - buffer.resize(desiredLength); - if (!stream.read(reinterpret_cast(buffer.data()), desiredLength)) - return NULL; - return buffer.data(); - } - bool SkipBuffer(unsigned desiredLength) override { - return (bool)stream.seekg(desiredLength, std::ios::cur); - } - private: - std::istream& stream; - std::vector buffer; - }; - EXIFStdStream streamWrapper(stream); - return parseFrom(streamWrapper); -} - - -int EXIFInfo::parseFrom(const uint8_t* buf, unsigned len) { - class EXIFStreamBuffer : public EXIFStream { - public: - explicit EXIFStreamBuffer(const uint8_t* buf, unsigned len) - : it(buf), end(buf+len) {} - bool IsValid() const override { - return it != NULL; - } - const uint8_t* GetBuffer(unsigned desiredLength) override { - const uint8_t* const itNext(it+desiredLength); - if (itNext >= end) - return NULL; - const uint8_t* const begin(it); - it = itNext; - return begin; - } - bool SkipBuffer(unsigned desiredLength) override { - return GetBuffer(desiredLength) != NULL; - } - private: - const uint8_t* it, * const end; - }; - EXIFStreamBuffer stream(buf, len); - return parseFrom(stream); -} - -// -// Main parsing function for an EXIF segment. -// Do a sanity check by looking for bytes "Exif\0\0". -// The marker has to contain at least the TIFF header, otherwise the -// JM_APP1 data is corrupt. So the minimum length specified here has to be: -// 6 bytes: "Exif\0\0" string -// 2 bytes: TIFF header (either "II" or "MM" string) -// 2 bytes: TIFF magic (short 0x2a00 in Motorola byte order) -// 4 bytes: Offset to first IFD -// ========= -// 14 bytes -// -// PARAM: 'buf' start of the EXIF TIFF, which must be the bytes "Exif\0\0". -// PARAM: 'len' length of buffer -// -int EXIFInfo::parseFromEXIFSegment(const uint8_t* buf, unsigned len) { - unsigned offs = 6; // current offset into buffer - if (!buf || len < offs) - return PARSE_ABSENT_DATA; - if (!std::equal(buf, buf+offs, "Exif\0\0")) - return PARSE_ABSENT_DATA; - - // Now parsing the TIFF header. The first two bytes are either "II" or - // "MM" for Intel or Motorola byte alignment. Sanity check by parsing - // the uint16_t that follows, making sure it equals 0x2a. The - // last 4 bytes are an offset into the first IFD, which are added to - // the global offset counter. For this block, we expect the following - // minimum size: - // 2 bytes: 'II' or 'MM' - // 2 bytes: 0x002a - // 4 bytes: offset to first IDF - // ----------------------------- - // 8 bytes - if (offs + 8 > len) - return PARSE_CORRUPT_DATA; - bool alignIntel; - if (buf[offs] == 'I' && buf[offs+1] == 'I') - alignIntel = true; // 1: Intel byte alignment - else - if (buf[offs] == 'M' && buf[offs+1] == 'M') - alignIntel = false; // 0: Motorola byte alignment - else - return PARSE_UNKNOWN_BYTEALIGN; - EntryParser parser(buf, len, offs, alignIntel); - offs += 2; - if (0x2a != EntryParser::parse16(buf + offs, alignIntel)) - return PARSE_CORRUPT_DATA; - offs += 2; - const unsigned first_ifd_offset = EntryParser::parse32(buf + offs, alignIntel); - offs += first_ifd_offset - 4; - if (offs >= len) - return PARSE_CORRUPT_DATA; - - // Now parsing the first Image File Directory (IFD0, for the main image). - // An IFD consists of a variable number of 12-byte directory entries. The - // first two bytes of the IFD section contain the number of directory - // entries in the section. The last 4 bytes of the IFD contain an offset - // to the next IFD, which means this IFD must contain exactly 6 + 12 * num - // bytes of data. - if (offs + 2 > len) - return PARSE_CORRUPT_DATA; - int num_entries = EntryParser::parse16(buf + offs, alignIntel); - if (offs + 6 + 12 * num_entries > len) - return PARSE_CORRUPT_DATA; - unsigned exif_sub_ifd_offset = len; - unsigned gps_sub_ifd_offset = len; - parser.Init(offs+2); - while (--num_entries >= 0) { - parser.ParseTag(); - parseIFDImage(parser, exif_sub_ifd_offset, gps_sub_ifd_offset); - } - - // Jump to the EXIF SubIFD if it exists and parse all the information - // there. Note that it's possible that the EXIF SubIFD doesn't exist. - // The EXIF SubIFD contains most of the interesting information that a - // typical user might want. - if (exif_sub_ifd_offset + 4 <= len) { - offs = exif_sub_ifd_offset; - num_entries = EntryParser::parse16(buf + offs, alignIntel); - if (offs + 6 + 12 * num_entries > len) - return PARSE_CORRUPT_DATA; - parser.Init(offs+2); - while (--num_entries >= 0) { - parser.ParseTag(); - parseIFDExif(parser); - } - } - - // Jump to the GPS SubIFD if it exists and parse all the information - // there. Note that it's possible that the GPS SubIFD doesn't exist. - if (gps_sub_ifd_offset + 4 <= len) { - offs = gps_sub_ifd_offset; - num_entries = EntryParser::parse16(buf + offs, alignIntel); - if (offs + 6 + 12 * num_entries > len) - return PARSE_CORRUPT_DATA; - parser.Init(offs+2); - while (--num_entries >= 0) { - parser.ParseTag(); - parseIFDGPS(parser); - } - GeoLocation.parseCoords(); - } - - return PARSE_SUCCESS; -} - -#ifndef TINYEXIF_NO_XMP_SUPPORT - -// -// Main parsing function for a XMP segment. -// Do a sanity check by looking for bytes "http://ns.adobe.com/xap/1.0/\0". -// So the minimum length specified here has to be: -// 29 bytes: "http://ns.adobe.com/xap/1.0/\0" string -// -// PARAM: 'buf' start of the XMP header, which must be the bytes "http://ns.adobe.com/xap/1.0/\0". -// PARAM: 'len' length of buffer -// -int EXIFInfo::parseFromXMPSegment(const uint8_t* buf, unsigned len) { - unsigned offs = 29; // current offset into buffer - if (!buf || len < offs) - return PARSE_ABSENT_DATA; - if (!std::equal(buf, buf+offs, "http://ns.adobe.com/xap/1.0/\0")) - return PARSE_ABSENT_DATA; - if (offs >= len) - return PARSE_CORRUPT_DATA; - return parseFromXMPSegmentXML((const char*)(buf + offs), len - offs); -} -int EXIFInfo::parseFromXMPSegmentXML(const char* szXML, unsigned len) { - // Skip xpacket end section so that tinyxml2 lib parses the section correctly. - const char* szEnd(Tools::strrnstr(szXML, "FirstChildElement("rdf:RDF")) == NULL || - (document=document->FirstChildElement("rdf:Description")) == NULL) - return PARSE_ABSENT_DATA; - - // Try parsing the XMP content for tiff details. - if (Orientation == 0) { - uint32_t _Orientation(0); - document->QueryUnsignedAttribute("tiff:Orientation", &_Orientation); - Orientation = (uint16_t)_Orientation; - } - if (ImageWidth == 0 && ImageHeight == 0) { - document->QueryUnsignedAttribute("tiff:ImageWidth", &ImageWidth); - if (document->QueryUnsignedAttribute("tiff:ImageHeight", &ImageHeight) != tinyxml2::XML_SUCCESS) - document->QueryUnsignedAttribute("tiff:ImageLength", &ImageHeight) ; - } - if (XResolution == 0 && YResolution == 0 && ResolutionUnit == 0) { - document->QueryDoubleAttribute("tiff:XResolution", &XResolution); - document->QueryDoubleAttribute("tiff:YResolution", &YResolution); - uint32_t _ResolutionUnit(0); - document->QueryUnsignedAttribute("tiff:ResolutionUnit", &_ResolutionUnit); - ResolutionUnit = (uint16_t)_ResolutionUnit; - } - - // Try parsing the XMP content for projection type. - { - const tinyxml2::XMLElement* const element(document->FirstChildElement("GPano:ProjectionType")); - if (element != NULL) { - const char* const szProjectionType(element->GetText()); - if (szProjectionType != NULL) { - if (0 == strcasecmp(szProjectionType, "perspective")) - ProjectionType = 1; - else - if (0 == strcasecmp(szProjectionType, "equirectangular") || - 0 == strcasecmp(szProjectionType, "spherical")) - ProjectionType = 2; - } - } - } - - // Try parsing the XMP content for supported maker's info. - struct ParseXMP { - // try yo fetch the value both from the attribute and child element - // and parse if needed rational numbers stored as string fraction - static bool Value(const tinyxml2::XMLElement* document, const char* name, double& value) { - const char* szAttribute = document->Attribute(name); - if (szAttribute == NULL) { - const tinyxml2::XMLElement* const element(document->FirstChildElement(name)); - if (element == NULL || (szAttribute=element->GetText()) == NULL) - return false; - } - std::vector values; - Tools::strSplit(szAttribute, '/', values); - switch (values.size()) { - case 1: value = strtod(values.front().c_str(), NULL); return true; - case 2: value = strtod(values.front().c_str(), NULL)/strtod(values.back().c_str(), NULL); return true; - } - return false; - } - // same as previous function but with unsigned int results - static bool Value(const tinyxml2::XMLElement* document, const char* name, uint32_t& value) { - const char* szAttribute = document->Attribute(name); - if (szAttribute == NULL) { - const tinyxml2::XMLElement* const element(document->FirstChildElement(name)); - if (element == NULL || (szAttribute = element->GetText()) == NULL) - return false; - } - value = strtoul(szAttribute, NULL, 0); return true; - return false; - } - }; - const char* szAbout(document->Attribute("rdf:about")); - if (0 == strcasecmp(Make.c_str(), "DJI") || (szAbout != NULL && 0 == strcasecmp(szAbout, "DJI Meta Data"))) { - ParseXMP::Value(document, "drone-dji:AbsoluteAltitude", GeoLocation.Altitude); - ParseXMP::Value(document, "drone-dji:RelativeAltitude", GeoLocation.RelativeAltitude); - ParseXMP::Value(document, "drone-dji:GimbalRollDegree", GeoLocation.RollDegree); - ParseXMP::Value(document, "drone-dji:GimbalPitchDegree", GeoLocation.PitchDegree); - ParseXMP::Value(document, "drone-dji:GimbalYawDegree", GeoLocation.YawDegree); - ParseXMP::Value(document, "drone-dji:CalibratedFocalLength", Calibration.FocalLength); - ParseXMP::Value(document, "drone-dji:CalibratedOpticalCenterX", Calibration.OpticalCenterX); - ParseXMP::Value(document, "drone-dji:CalibratedOpticalCenterY", Calibration.OpticalCenterY); - } else - if (0 == strcasecmp(Make.c_str(), "senseFly") || 0 == strcasecmp(Make.c_str(), "Sentera")) { - ParseXMP::Value(document, "Camera:Roll", GeoLocation.RollDegree); - if (ParseXMP::Value(document, "Camera:Pitch", GeoLocation.PitchDegree)) { - // convert to DJI format: senseFly uses pitch 0 as NADIR, whereas DJI -90 - GeoLocation.PitchDegree = Tools::NormD180(GeoLocation.PitchDegree-90.0); - } - ParseXMP::Value(document, "Camera:Yaw", GeoLocation.YawDegree); - ParseXMP::Value(document, "Camera:GPSXYAccuracy", GeoLocation.AccuracyXY); - ParseXMP::Value(document, "Camera:GPSZAccuracy", GeoLocation.AccuracyZ); - } else - if (0 == strcasecmp(Make.c_str(), "PARROT")) { - ParseXMP::Value(document, "Camera:Roll", GeoLocation.RollDegree) || - ParseXMP::Value(document, "drone-parrot:CameraRollDegree", GeoLocation.RollDegree); - if (ParseXMP::Value(document, "Camera:Pitch", GeoLocation.PitchDegree) || - ParseXMP::Value(document, "drone-parrot:CameraPitchDegree", GeoLocation.PitchDegree)) { - // convert to DJI format: senseFly uses pitch 0 as NADIR, whereas DJI -90 - GeoLocation.PitchDegree = Tools::NormD180(GeoLocation.PitchDegree-90.0); - } - ParseXMP::Value(document, "Camera:Yaw", GeoLocation.YawDegree) || - ParseXMP::Value(document, "drone-parrot:CameraYawDegree", GeoLocation.YawDegree); - ParseXMP::Value(document, "Camera:AboveGroundAltitude", GeoLocation.RelativeAltitude); - } - ParseXMP::Value(document, "GPano:PosePitchDegrees", GPano.PosePitchDegrees); - ParseXMP::Value(document, "GPano:PoseRollDegrees", GPano.PoseRollDegrees); - - // parse GCamera:MicroVideo - if (document->Attribute("GCamera:MicroVideo")) { - ParseXMP::Value(document, "GCamera:MicroVideo", MicroVideo.HasMicroVideo); - ParseXMP::Value(document, "GCamera:MicroVideoVersion", MicroVideo.MicroVideoVersion); - ParseXMP::Value(document, "GCamera:MicroVideoOffset", MicroVideo.MicroVideoOffset); - } - return PARSE_SUCCESS; -} - -#endif // TINYEXIF_NO_XMP_SUPPORT - -void EXIFInfo::Geolocation_t::parseCoords() { - // Convert GPS latitude - if (LatComponents.degrees != DBL_MAX || - LatComponents.minutes != 0 || - LatComponents.seconds != 0) { - Latitude = - LatComponents.degrees + - LatComponents.minutes / 60 + - LatComponents.seconds / 3600; - if ('S' == LatComponents.direction) - Latitude = -Latitude; - } - // Convert GPS longitude - if (LonComponents.degrees != DBL_MAX || - LonComponents.minutes != 0 || - LonComponents.seconds != 0) { - Longitude = - LonComponents.degrees + - LonComponents.minutes / 60 + - LonComponents.seconds / 3600; - if ('W' == LonComponents.direction) - Longitude = -Longitude; - } - // Convert GPS altitude - if (hasAltitude() && - AltitudeRef == 1) { - Altitude = -Altitude; - } -} - -bool EXIFInfo::Geolocation_t::hasLatLon() const { - return Latitude != DBL_MAX && Longitude != DBL_MAX; -} -bool EXIFInfo::Geolocation_t::hasAltitude() const { - return Altitude != DBL_MAX; -} -bool EXIFInfo::Geolocation_t::hasRelativeAltitude() const { - return RelativeAltitude != DBL_MAX; -} -bool EXIFInfo::Geolocation_t::hasOrientation() const { - return RollDegree != DBL_MAX && PitchDegree != DBL_MAX && YawDegree != DBL_MAX; -} -bool EXIFInfo::Geolocation_t::hasSpeed() const { - return SpeedX != DBL_MAX && SpeedY != DBL_MAX && SpeedZ != DBL_MAX; -} - -bool EXIFInfo::GPano_t::hasPosePitchDegrees() const { - return PosePitchDegrees != DBL_MAX; -} - -bool EXIFInfo::GPano_t::hasPoseRollDegrees() const { - return PoseRollDegrees != DBL_MAX; -} - -void EXIFInfo::clear() { - Fields = FIELD_NA; - - // Strings - ImageDescription = ""; - Make = ""; - Model = ""; - SerialNumber = ""; - Software = ""; - DateTime = ""; - DateTimeOriginal = ""; - DateTimeDigitized = ""; - SubSecTimeOriginal= ""; - Copyright = ""; - - // Shorts / unsigned / double - ImageWidth = 0; - ImageHeight = 0; - RelatedImageWidth = 0; - RelatedImageHeight= 0; - Orientation = 0; - XResolution = 0; - YResolution = 0; - ResolutionUnit = 0; - BitsPerSample = 0; - ExposureTime = 0; - FNumber = 0; - ExposureProgram = 0; - ISOSpeedRatings = 0; - ShutterSpeedValue = 0; - ApertureValue = 0; - BrightnessValue = 0; - ExposureBiasValue = 0; - SubjectDistance = 0; - FocalLength = 0; - Flash = 0; - MeteringMode = 0; - LightSource = 0; - ProjectionType = 0; - SubjectArea.clear(); - - // Calibration - Calibration.FocalLength = 0; - Calibration.OpticalCenterX = 0; - Calibration.OpticalCenterY = 0; - - // LensInfo - LensInfo.FocalLengthMax = 0; - LensInfo.FocalLengthMin = 0; - LensInfo.FStopMax = 0; - LensInfo.FStopMin = 0; - LensInfo.DigitalZoomRatio = 0; - LensInfo.FocalLengthIn35mm = 0; - LensInfo.FocalPlaneXResolution = 0; - LensInfo.FocalPlaneYResolution = 0; - LensInfo.FocalPlaneResolutionUnit = 0; - LensInfo.Make = ""; - LensInfo.Model = ""; - - // Geolocation - GeoLocation.Latitude = DBL_MAX; - GeoLocation.Longitude = DBL_MAX; - GeoLocation.Altitude = DBL_MAX; - GeoLocation.AltitudeRef = 0; - GeoLocation.RelativeAltitude = DBL_MAX; - GeoLocation.RollDegree = DBL_MAX; - GeoLocation.PitchDegree = DBL_MAX; - GeoLocation.YawDegree = DBL_MAX; - GeoLocation.SpeedX = DBL_MAX; - GeoLocation.SpeedY = DBL_MAX; - GeoLocation.SpeedZ = DBL_MAX; - GeoLocation.AccuracyXY = 0; - GeoLocation.AccuracyZ = 0; - GeoLocation.GPSDOP = 0; - GeoLocation.GPSDifferential = 0; - GeoLocation.GPSMapDatum = ""; - GeoLocation.GPSTimeStamp = ""; - GeoLocation.GPSDateStamp = ""; - GeoLocation.LatComponents.degrees = DBL_MAX; - GeoLocation.LatComponents.minutes = 0; - GeoLocation.LatComponents.seconds = 0; - GeoLocation.LatComponents.direction = 0; - GeoLocation.LonComponents.degrees = DBL_MAX; - GeoLocation.LonComponents.minutes = 0; - GeoLocation.LonComponents.seconds = 0; - GeoLocation.LonComponents.direction = 0; - - // GPano - GPano.PosePitchDegrees = DBL_MAX; - GPano.PoseRollDegrees = DBL_MAX; - - // Video metadata - MicroVideo.HasMicroVideo = 0; - MicroVideo.MicroVideoVersion = 0; - MicroVideo.MicroVideoOffset = 0; -} - -} // namespace TinyEXIF diff --git a/addon/TinyEXIF/TinyEXIF.h b/addon/TinyEXIF/TinyEXIF.h deleted file mode 100644 index 56354aa8..00000000 --- a/addon/TinyEXIF/TinyEXIF.h +++ /dev/null @@ -1,320 +0,0 @@ -/* - TinyEXIF.h -- A simple ISO C++ library to parse basic EXIF and XMP - information from a JPEG file. - - Copyright (c) 2015-2017 Seacave - cdc.seacave@gmail.com - All rights reserved. - - Based on the easyexif library (2013 version) - https://github.com/mayanklahiri/easyexif - of Mayank Lahiri (mlahiri@gmail.com). - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef __TINYEXIF_H__ -#define __TINYEXIF_H__ - -#include -#include - -#define TINYEXIF_MAJOR_VERSION 1 -#define TINYEXIF_MINOR_VERSION 0 -#define TINYEXIF_PATCH_VERSION 1 - -#ifdef _MSC_VER -# ifdef TINYEXIF_EXPORT -# define TINYEXIF_LIB __declspec(dllexport) -# elif defined(TINYEXIF_IMPORT) -# define TINYEXIF_LIB __declspec(dllimport) -# else -# define TINYEXIF_LIB -# endif -#elif __GNUC__ >= 4 -# define TINYEXIF_LIB __attribute__((visibility("default"))) -#else -# define TINYEXIF_LIB -#endif - -namespace TinyEXIF { - -enum ErrorCode { - PARSE_SUCCESS = 0, // Parse EXIF and/or XMP was successful - PARSE_INVALID_JPEG = 1, // No JPEG markers found in buffer, possibly invalid JPEG file - PARSE_UNKNOWN_BYTEALIGN = 2, // Byte alignment specified in EXIF file was unknown (neither Motorola nor Intel) - PARSE_ABSENT_DATA = 3, // No EXIF and/or XMP data found in JPEG file - PARSE_CORRUPT_DATA = 4, // EXIF and/or XMP header was found, but data was corrupted -}; - -enum FieldCode { - FIELD_NA = 0, // No EXIF or XMP data - FIELD_EXIF = (1 << 0), // EXIF data available - FIELD_XMP = (1 << 1), // XMP data available - FIELD_ALL = FIELD_EXIF|FIELD_XMP -}; - -class EntryParser; - -// -// Interface class responsible for fetching stream data to be parsed -// -class TINYEXIF_LIB EXIFStream { -public: - virtual ~EXIFStream() {} - - // Check the state of the stream. - virtual bool IsValid() const = 0; - - // Return the pointer to the beginning of the desired size buffer - // following current buffer position. - virtual const uint8_t* GetBuffer(unsigned desiredLength) = 0; - - // Advance current buffer position with the desired size; - // return false if stream ends in less than the desired size. - virtual bool SkipBuffer(unsigned desiredLength) = 0; -}; - -// -// Class responsible for storing and parsing EXIF & XMP metadata from a JPEG stream -// -class TINYEXIF_LIB EXIFInfo { -public: - EXIFInfo(); - EXIFInfo(EXIFStream& stream); - EXIFInfo(std::istream& stream); // NB: the stream must have been opened in binary mode - EXIFInfo(const uint8_t* data, unsigned length); - - // Parsing function for an entire JPEG image stream. - // - // PARAM 'stream': Interface to fetch JPEG image stream. - // PARAM 'data': A pointer to a JPEG image. - // PARAM 'length': The length of the JPEG image. - // RETURN: PARSE_SUCCESS (0) on success with 'result' filled out - // error code otherwise, as defined by the PARSE_* macros - int parseFrom(EXIFStream& stream); - int parseFrom(std::istream& stream); // NB: the stream must have been opened in binary mode - int parseFrom(const uint8_t* data, unsigned length); - - // Parsing function for an EXIF segment. This is used internally by parseFrom() - // but can be called for special cases where only the EXIF section is - // available (i.e., a blob starting with the bytes "Exif\0\0"). - int parseFromEXIFSegment(const uint8_t* buf, unsigned len); - -#ifndef TINYEXIF_NO_XMP_SUPPORT - // Parsing function for an XMP segment. This is used internally by parseFrom() - // but can be called for special cases where only the XMP section is - // available (i.e., a blob starting with the bytes "http://ns.adobe.com/xap/1.0/\0"). - int parseFromXMPSegment(const uint8_t* buf, unsigned len); - int parseFromXMPSegmentXML(const char* szXML, unsigned len); -#endif // TINYEXIF_NO_XMP_SUPPORT - - // Set all data members to default values. - // Should be called before parsing a new stream. - void clear(); - -private: - // Parse tag as Image IFD. - void parseIFDImage(EntryParser&, unsigned&, unsigned&); - // Parse tag as Exif IFD. - void parseIFDExif(EntryParser&); - // Parse tag as GPS IFD. - void parseIFDGPS(EntryParser&); - // Parse tag as MakerNote IFD. - void parseIFDMakerNote(EntryParser&); - -public: - // Data fields - uint32_t Fields; // Store if EXIF and/or XMP data fields are available - uint32_t ImageWidth; // Image width reported in EXIF data - uint32_t ImageHeight; // Image height reported in EXIF data - uint32_t RelatedImageWidth; // Original image width reported in EXIF data - uint32_t RelatedImageHeight; // Original image height reported in EXIF data - std::string ImageDescription; // Image description - std::string Make; // Camera manufacturer's name - std::string Model; // Camera model - std::string SerialNumber; // Serial number of the body of the camera - uint16_t Orientation; // Image orientation, start of data corresponds to - // 0: unspecified in EXIF data - // 1: upper left of image - // 3: lower right of image - // 6: upper right of image - // 8: lower left of image - // 9: undefined - double XResolution; // Number of pixels per ResolutionUnit in the ImageWidth direction - double YResolution; // Number of pixels per ResolutionUnit in the ImageLength direction - uint16_t ResolutionUnit; // Unit of measurement for XResolution and YResolution - // 1: no absolute unit of measurement. Used for images that may have a non-square aspect ratio, but no meaningful absolute dimensions - // 2: inch - // 3: centimeter - uint16_t BitsPerSample; // Number of bits per component - std::string Software; // Software used - std::string DateTime; // File change date and time - std::string DateTimeOriginal; // Original file date and time (may not exist) - std::string DateTimeDigitized; // Digitization date and time (may not exist) - std::string SubSecTimeOriginal; // Sub-second time that original picture was taken - std::string Copyright; // File copyright information - double ExposureTime; // Exposure time in seconds - double FNumber; // F/stop - uint16_t ExposureProgram; // Exposure program - // 0: not defined - // 1: manual - // 2: normal program - // 3: aperture priority - // 4: shutter priority - // 5: creative program - // 6: action program - // 7: portrait mode - // 8: landscape mode - uint16_t ISOSpeedRatings; // ISO speed - double ShutterSpeedValue; // Shutter speed (reciprocal of exposure time) - double ApertureValue; // The lens aperture - double BrightnessValue; // The value of brightness - double ExposureBiasValue; // Exposure bias value in EV - double SubjectDistance; // Distance to focus point in meters - double FocalLength; // Focal length of lens in millimeters - uint16_t Flash; // Flash info - // Flash used (Flash&1) - // 0: no flash, >0: flash used - // Flash returned light status ((Flash & 6) >> 1) - // 0: no strobe return detection function - // 1: reserved - // 2: strobe return light not detected - // 3: strobe return light detected - // Flash mode ((Flash & 24) >> 3) - // 0: unknown - // 1: compulsory flash firing - // 2: compulsory flash suppression - // 3: auto mode - // Flash function ((Flash & 32) >> 5) - // 0: flash function present, >0: no flash function - // Flash red-eye ((Flash & 64) >> 6) - // 0: no red-eye reduction mode or unknown, >0: red-eye reduction supported - uint16_t MeteringMode; // Metering mode - // 0: unknown - // 1: average - // 2: center weighted average - // 3: spot - // 4: multi-spot - // 5: pattern - // 6: partial - uint16_t LightSource; // Kind of light source - // 0: unknown - // 1: daylight - // 2: fluorescent - // 3: tungsten (incandescent light) - // 4: flash - // 9: fine weather - // 10: cloudy weather - // 11: shade - // 12: daylight fluorescent (D 5700 - 7100K) - // 13: day white fluorescent (N 4600 - 5400K) - // 14: cool white fluorescent (W 3900 - 4500K) - // 15: white fluorescent (WW 3200 - 3700K) - // 17: standard light A - // 18: standard light B - // 19: standard light C - // 20: D55 - // 21: D65 - // 22: D75 - // 23: D50 - // 24: ISO studio tungsten - uint16_t ProjectionType; // Projection type - // 0: unknown projection - // 1: perspective projection - // 2: equirectangular/spherical projection - std::vector SubjectArea; // Location and area of the main subject in the overall scene expressed in relation to the upper left as origin, prior to rotation - // 0: unknown - // 2: location of the main subject as coordinates (first value is the X coordinate and second is the Y coordinate) - // 3: area of the main subject as a circle (first value is the center X coordinate, second is the center Y coordinate, and third is the diameter) - // 4: area of the main subject as a rectangle (first value is the center X coordinate, second is the center Y coordinate, third is the width of the area, and fourth is the height of the area) - struct TINYEXIF_LIB Calibration_t { // Camera calibration information - double FocalLength; // Focal length (pixels) - double OpticalCenterX; // Principal point X (pixels) - double OpticalCenterY; // Principal point Y (pixels) - } Calibration; - struct TINYEXIF_LIB LensInfo_t { // Lens information - double FStopMin; // Min aperture (f-stop) - double FStopMax; // Max aperture (f-stop) - double FocalLengthMin; // Min focal length (mm) - double FocalLengthMax; // Max focal length (mm) - double DigitalZoomRatio; // Digital zoom ratio when the image was shot - double FocalLengthIn35mm; // Focal length in 35mm film - double FocalPlaneXResolution; // Number of pixels in the image width (X) direction per FocalPlaneResolutionUnit on the camera focal plane (may not exist) - double FocalPlaneYResolution; // Number of pixels in the image width (Y) direction per FocalPlaneResolutionUnit on the camera focal plane (may not exist) - uint16_t FocalPlaneResolutionUnit;// Unit for measuring FocalPlaneXResolution and FocalPlaneYResolution (may not exist) - // 0: unspecified in EXIF data - // 1: no absolute unit of measurement - // 2: inch - // 3: centimeter - std::string Make; // Lens manufacturer - std::string Model; // Lens model - } LensInfo; - struct TINYEXIF_LIB Geolocation_t { // GPS information embedded in file - double Latitude; // Image latitude expressed as decimal - double Longitude; // Image longitude expressed as decimal - double Altitude; // Altitude in meters, relative to sea level - int8_t AltitudeRef; // 0: above sea level, -1: below sea level - double RelativeAltitude; // Relative altitude in meters - double RollDegree; // Flight roll in degrees - double PitchDegree; // Flight pitch in degrees - double YawDegree; // Flight yaw in degrees - double SpeedX; // Flight speed on X in meters/second - double SpeedY; // Flight speed on Y in meters/second - double SpeedZ; // Flight speed on Z in meters/second - double AccuracyXY; // GPS accuracy on XY in meters - double AccuracyZ; // GPS accuracy on Z in meters - double GPSDOP; // GPS DOP (data degree of precision) - uint16_t GPSDifferential; // Differential correction applied to the GPS receiver (may not exist) - // 0: measurement without differential correction - // 1: differential correction applied - std::string GPSMapDatum; // Geodetic survey data (may not exist) - std::string GPSTimeStamp; // Time as UTC (Coordinated Universal Time) (may not exist) - std::string GPSDateStamp; // A character string recording date and time information relative to UTC (Coordinated Universal Time) YYYY:MM:DD (may not exist) - struct Coord_t { - double degrees; - double minutes; - double seconds; - uint8_t direction; - } LatComponents, LonComponents; // Latitude/Longitude expressed in deg/min/sec - void parseCoords(); // Convert Latitude/Longitude from deg/min/sec to decimal - bool hasLatLon() const; // Return true if (lat,lon) is available - bool hasAltitude() const; // Return true if (alt) is available - bool hasRelativeAltitude()const;// Return true if (rel_alt) is available - bool hasOrientation() const; // Return true if (roll,yaw,pitch) is available - bool hasSpeed() const; // Return true if (speedX,speedY,speedZ) is available - } GeoLocation; - struct TINYEXIF_LIB GPano_t { // Spherical metadata. https://developers.google.com/streetview/spherical-metadata - double PosePitchDegrees; // Pitch, measured in degrees above the horizon, for the center in the image. Value must be >= -90 and <= 90. - double PoseRollDegrees; // Roll, measured in degrees, of the image where level with the horizon is 0. As roll increases, the horizon rotates counterclockwise in the image. Value must be > -180 and <= 180. - bool hasPosePitchDegrees() const; // Return true if PosePitchDegrees is available - bool hasPoseRollDegrees() const; // Return true if PoseRollDegrees is available - } GPano; - struct TINYEXIF_LIB MicroVideo_t { // Google camera video file in metadata - uint32_t HasMicroVideo; // not zero if exists - uint32_t MicroVideoVersion; // just regularinfo - uint32_t MicroVideoOffset; // offset from end of file - } MicroVideo; -}; - -} // namespace TinyEXIF - -#endif // __TINYEXIF_H__ diff --git a/addon/api.cpp b/addon/api.cpp index f093c758..c0fd0730 100644 --- a/addon/api.cpp +++ b/addon/api.cpp @@ -1,146 +1,14 @@ -// Defines the entry point for the console application. - -#ifdef _MSC_VER -#include -#endif -#include "./TinyEXIF/TinyEXIF.h" -#include // std::cout -#include // std::ifstream -#include // std::vector -#include // std::setprecision #include -using namespace Napi; - - -Array vectorToNapiArray(std::vector arr, Env env){ - Array array = Array::New(env); - int i = 0; - for (uint16_t val: arr){ - array[i] = val; - i++; - } - return array; -} - - -static Napi::Value getEXIF(const Napi::CallbackInfo& info) { - Env env = info.Env(); - String _path = info[0].As(); - std::string path = _path.Utf8Value().c_str(); - std::ifstream stream(path, std::ios::binary); - TinyEXIF::EXIFInfo imageEXIF(stream); - stream.close(); - Napi::Object o = Napi::Object::New(env); - o.Set("ImageWidth",imageEXIF.ImageWidth); - o.Set("ImageHeight",imageEXIF.ImageHeight); - o.Set("RelatedImageWidth",imageEXIF.RelatedImageWidth); - o.Set("RelatedImageHeight",imageEXIF.RelatedImageHeight); - o.Set("ImageDescription",imageEXIF.ImageDescription); - o.Set("Make",imageEXIF.Make); - o.Set("Model",imageEXIF.Model); - o.Set("SerialNumber",imageEXIF.SerialNumber); - o.Set("Orientation",imageEXIF.Orientation); - o.Set("XResolution",imageEXIF.XResolution); - o.Set("YResolution",imageEXIF.YResolution); - o.Set("ResolutionUnit",imageEXIF.ResolutionUnit); - o.Set("BitsPerSample",imageEXIF.BitsPerSample); - o.Set("Software",imageEXIF.Software); - o.Set("DateTime",imageEXIF.DateTime); - o.Set("DateTimeOriginal",imageEXIF.DateTimeOriginal); - o.Set("DateTimeDigitized",imageEXIF.DateTimeDigitized); - o.Set("SubSecTimeOriginal",imageEXIF.SubSecTimeOriginal); - o.Set("ExposureTime",imageEXIF.ExposureTime); - o.Set("Copyright",imageEXIF.Copyright); - o.Set("FNumber",imageEXIF.FNumber); - o.Set("ExposureProgram",imageEXIF.ExposureProgram); - o.Set("ISOSpeedRatings",imageEXIF.ISOSpeedRatings); - o.Set("ShutterSpeedValue",imageEXIF.ShutterSpeedValue); - o.Set("ApertureValue",imageEXIF.ApertureValue); - o.Set("BrightnessValue",imageEXIF.BrightnessValue); - o.Set("ExposureBiasValue",imageEXIF.ExposureBiasValue); - o.Set("SubjectDistance",imageEXIF.SubjectDistance); - o.Set("FocalLength",imageEXIF.FocalLength); - o.Set("Flash",imageEXIF.Flash); - if (!imageEXIF.SubjectArea.empty()) { - o.Set("SubjectArea",vectorToNapiArray(imageEXIF.SubjectArea,env)); - } - - o.Set("MeteringMode",imageEXIF.MeteringMode); - o.Set("LightSource",imageEXIF.LightSource); - o.Set("ProjectionType",imageEXIF.ProjectionType); - Object Calibration = Object::New(env); - Calibration.Set("FocalLength",imageEXIF.Calibration.FocalLength); - Calibration.Set("OpticalCenterX",imageEXIF.Calibration.OpticalCenterX); - Calibration.Set("OpticalCenterY",imageEXIF.Calibration.OpticalCenterY); - o.Set("Calibration",Calibration); - Object LensInfo = Object::New(env); - LensInfo.Set("FStopMin",imageEXIF.LensInfo.FStopMin); - LensInfo.Set("FStopMax",imageEXIF.LensInfo.FStopMax); - LensInfo.Set("FocalLengthMin",imageEXIF.LensInfo.FocalLengthMin); - LensInfo.Set("FocalLengthMax",imageEXIF.LensInfo.FocalLengthMax); - LensInfo.Set("DigitalZoomRatio",imageEXIF.LensInfo.DigitalZoomRatio); - LensInfo.Set("FocalLengthIn35mm",imageEXIF.LensInfo.FocalLengthIn35mm); - LensInfo.Set("FocalPlaneXResolution",imageEXIF.LensInfo.FocalPlaneXResolution); - LensInfo.Set("FocalPlaneYResolution",imageEXIF.LensInfo.FocalPlaneYResolution); - LensInfo.Set("FocalPlaneResolutionUnit",imageEXIF.LensInfo.FocalPlaneResolutionUnit); - if (!imageEXIF.LensInfo.Make.empty()) { - LensInfo.Set("Make",imageEXIF.LensInfo.Make); - } - if (!imageEXIF.LensInfo.Model.empty()) { - LensInfo.Set("Model",imageEXIF.LensInfo.Model); - } - - o.Set("LensInfo",LensInfo); - Object GeoLocation = Object::New(env); - if (imageEXIF.GeoLocation.hasLatLon()) { - GeoLocation.Set("Latitude",imageEXIF.GeoLocation.Latitude); - GeoLocation.Set("Longitude",imageEXIF.GeoLocation.Longitude); - } - - if (imageEXIF.GeoLocation.hasAltitude()) { - GeoLocation.Set("Altitude",imageEXIF.GeoLocation.Altitude); - GeoLocation.Set("AltitudeRef",imageEXIF.GeoLocation.AltitudeRef); - } - - if (imageEXIF.GeoLocation.hasRelativeAltitude()) { - GeoLocation.Set("RelativeAltitude",imageEXIF.GeoLocation.RelativeAltitude); - } - - if (imageEXIF.GeoLocation.hasOrientation()) { - GeoLocation.Set("RollDegree",imageEXIF.GeoLocation.RollDegree); - GeoLocation.Set("PitchDegree",imageEXIF.GeoLocation.PitchDegree); - GeoLocation.Set("YawDegree",imageEXIF.GeoLocation.YawDegree); - } - if (imageEXIF.GeoLocation.hasSpeed()) { - GeoLocation.Set("SpeedX",imageEXIF.GeoLocation.SpeedX); - GeoLocation.Set("SpeedY",imageEXIF.GeoLocation.SpeedY); - GeoLocation.Set("SpeedZ",imageEXIF.GeoLocation.SpeedZ); - } - GeoLocation.Set("AccuracyXY",imageEXIF.GeoLocation.AccuracyXY); - GeoLocation.Set("AccuracyZ",imageEXIF.GeoLocation.AccuracyZ); - GeoLocation.Set("GPSDOP",imageEXIF.GeoLocation.GPSDOP); - GeoLocation.Set("GPSDifferential",imageEXIF.GeoLocation.GPSDifferential); - if (!imageEXIF.GeoLocation.GPSMapDatum.empty()) - GeoLocation.Set("GPSMapDatum",imageEXIF.GeoLocation.GPSMapDatum); - if (!imageEXIF.GeoLocation.GPSTimeStamp.empty()) - GeoLocation.Set("GPSTimeStamp",imageEXIF.GeoLocation.GPSTimeStamp); - if (!imageEXIF.GeoLocation.GPSDateStamp.empty()) - GeoLocation.Set("GPSDateStamp",imageEXIF.GeoLocation.GPSDateStamp); - o.Set("GeoLocation",GeoLocation); - Object GPano = Object::New(env); - if(imageEXIF.GPano.hasPosePitchDegrees()) - GPano.Set("PosePitchDegrees",imageEXIF.GPano.PosePitchDegrees); - if(imageEXIF.GPano.hasPoseRollDegrees()) - GPano.Set("PoseRollDegrees",imageEXIF.GPano.PoseRollDegrees); - o.Set("GPano",GPano); - imageEXIF.clear(); - return o; +static Napi::Value hello(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::String name = info[0].As(); + return Napi::String::New(env, "Hello " + name.Utf8Value() + "!"); } static Napi::Object Init(Napi::Env env, Napi::Object exports) { - exports["getEXIF"] = Napi::Function::New(env, getEXIF); + exports["hello"] = Napi::Function::New(env, hello); return exports; } diff --git a/addon/tinyxml2/tinyxml2.cpp b/addon/tinyxml2/tinyxml2.cpp deleted file mode 100755 index 3cbe174c..00000000 --- a/addon/tinyxml2/tinyxml2.cpp +++ /dev/null @@ -1,2987 +0,0 @@ -/* -Original code by Lee Thomason (www.grinninglizard.com) - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must -not claim that you wrote the original software. If you use this -software in a product, an acknowledgment in the product documentation -would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. -*/ - -#include "tinyxml2.h" - -#include // yes, this one new style header, is in the Android SDK. -#if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__) -# include -# include -#else -# include -# include -#endif - -#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) && (!defined WINCE) - // Microsoft Visual Studio, version 2005 and higher. Not WinCE. - /*int _snprintf_s( - char *buffer, - size_t sizeOfBuffer, - size_t count, - const char *format [, - argument] ... - );*/ - static inline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... ) - { - va_list va; - va_start( va, format ); - const int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va ); - va_end( va ); - return result; - } - - static inline int TIXML_VSNPRINTF( char* buffer, size_t size, const char* format, va_list va ) - { - const int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va ); - return result; - } - - #define TIXML_VSCPRINTF _vscprintf - #define TIXML_SSCANF sscanf_s -#elif defined _MSC_VER - // Microsoft Visual Studio 2003 and earlier or WinCE - #define TIXML_SNPRINTF _snprintf - #define TIXML_VSNPRINTF _vsnprintf - #define TIXML_SSCANF sscanf - #if (_MSC_VER < 1400 ) && (!defined WINCE) - // Microsoft Visual Studio 2003 and not WinCE. - #define TIXML_VSCPRINTF _vscprintf // VS2003's C runtime has this, but VC6 C runtime or WinCE SDK doesn't have. - #else - // Microsoft Visual Studio 2003 and earlier or WinCE. - static inline int TIXML_VSCPRINTF( const char* format, va_list va ) - { - int len = 512; - for (;;) { - len = len*2; - char* str = new char[len](); - const int required = _vsnprintf(str, len, format, va); - delete[] str; - if ( required != -1 ) { - TIXMLASSERT( required >= 0 ); - len = required; - break; - } - } - TIXMLASSERT( len >= 0 ); - return len; - } - #endif -#else - // GCC version 3 and higher - //#warning( "Using sn* functions." ) - #define TIXML_SNPRINTF snprintf - #define TIXML_VSNPRINTF vsnprintf - static inline int TIXML_VSCPRINTF( const char* format, va_list va ) - { - int len = vsnprintf( 0, 0, format, va ); - TIXMLASSERT( len >= 0 ); - return len; - } - #define TIXML_SSCANF sscanf -#endif - -#if defined(_WIN64) - #define TIXML_FSEEK _fseeki64 - #define TIXML_FTELL _ftelli64 -#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) \ - || defined(__NetBSD__) || defined(__DragonFly__) || defined(__ANDROID__) - #define TIXML_FSEEK fseeko - #define TIXML_FTELL ftello -#elif defined(__unix__) && defined(__x86_64__) - #define TIXML_FSEEK fseeko64 - #define TIXML_FTELL ftello64 -#else - #define TIXML_FSEEK fseek - #define TIXML_FTELL ftell -#endif - - -static const char LINE_FEED = static_cast(0x0a); // all line endings are normalized to LF -static const char LF = LINE_FEED; -static const char CARRIAGE_RETURN = static_cast(0x0d); // CR gets filtered out -static const char CR = CARRIAGE_RETURN; -static const char SINGLE_QUOTE = '\''; -static const char DOUBLE_QUOTE = '\"'; - -// Bunch of unicode info at: -// http://www.unicode.org/faq/utf_bom.html -// ef bb bf (Microsoft "lead bytes") - designates UTF-8 - -static const unsigned char TIXML_UTF_LEAD_0 = 0xefU; -static const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; -static const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; - -namespace tinyxml2 -{ - -struct Entity { - const char* pattern; - int length; - char value; -}; - -static const int NUM_ENTITIES = 5; -static const Entity entities[NUM_ENTITIES] = { - { "quot", 4, DOUBLE_QUOTE }, - { "amp", 3, '&' }, - { "apos", 4, SINGLE_QUOTE }, - { "lt", 2, '<' }, - { "gt", 2, '>' } -}; - - -StrPair::~StrPair() -{ - Reset(); -} - - -void StrPair::TransferTo( StrPair* other ) -{ - if ( this == other ) { - return; - } - // This in effect implements the assignment operator by "moving" - // ownership (as in auto_ptr). - - TIXMLASSERT( other != 0 ); - TIXMLASSERT( other->_flags == 0 ); - TIXMLASSERT( other->_start == 0 ); - TIXMLASSERT( other->_end == 0 ); - - other->Reset(); - - other->_flags = _flags; - other->_start = _start; - other->_end = _end; - - _flags = 0; - _start = 0; - _end = 0; -} - - -void StrPair::Reset() -{ - if ( _flags & NEEDS_DELETE ) { - delete [] _start; - } - _flags = 0; - _start = 0; - _end = 0; -} - - -void StrPair::SetStr( const char* str, int flags ) -{ - TIXMLASSERT( str ); - Reset(); - size_t len = strlen( str ); - TIXMLASSERT( _start == 0 ); - _start = new char[ len+1 ]; - memcpy( _start, str, len+1 ); - _end = _start + len; - _flags = flags | NEEDS_DELETE; -} - - -char* StrPair::ParseText( char* p, const char* endTag, int strFlags, int* curLineNumPtr ) -{ - TIXMLASSERT( p ); - TIXMLASSERT( endTag && *endTag ); - TIXMLASSERT(curLineNumPtr); - - char* start = p; - const char endChar = *endTag; - size_t length = strlen( endTag ); - - // Inner loop of text parsing. - while ( *p ) { - if ( *p == endChar && strncmp( p, endTag, length ) == 0 ) { - Set( start, p, strFlags ); - return p + length; - } else if (*p == '\n') { - ++(*curLineNumPtr); - } - ++p; - TIXMLASSERT( p ); - } - return 0; -} - - -char* StrPair::ParseName( char* p ) -{ - if ( !p || !(*p) ) { - return 0; - } - if ( !XMLUtil::IsNameStartChar( (unsigned char) *p ) ) { - return 0; - } - - char* const start = p; - ++p; - while ( *p && XMLUtil::IsNameChar( (unsigned char) *p ) ) { - ++p; - } - - Set( start, p, 0 ); - return p; -} - - -void StrPair::CollapseWhitespace() -{ - // Adjusting _start would cause undefined behavior on delete[] - TIXMLASSERT( ( _flags & NEEDS_DELETE ) == 0 ); - // Trim leading space. - _start = XMLUtil::SkipWhiteSpace( _start, 0 ); - - if ( *_start ) { - const char* p = _start; // the read pointer - char* q = _start; // the write pointer - - while( *p ) { - if ( XMLUtil::IsWhiteSpace( *p )) { - p = XMLUtil::SkipWhiteSpace( p, 0 ); - if ( *p == 0 ) { - break; // don't write to q; this trims the trailing space. - } - *q = ' '; - ++q; - } - *q = *p; - ++q; - ++p; - } - *q = 0; - } -} - - -const char* StrPair::GetStr() -{ - TIXMLASSERT( _start ); - TIXMLASSERT( _end ); - if ( _flags & NEEDS_FLUSH ) { - *_end = 0; - _flags ^= NEEDS_FLUSH; - - if ( _flags ) { - const char* p = _start; // the read pointer - char* q = _start; // the write pointer - - while( p < _end ) { - if ( (_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == CR ) { - // CR-LF pair becomes LF - // CR alone becomes LF - // LF-CR becomes LF - if ( *(p+1) == LF ) { - p += 2; - } - else { - ++p; - } - *q = LF; - ++q; - } - else if ( (_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == LF ) { - if ( *(p+1) == CR ) { - p += 2; - } - else { - ++p; - } - *q = LF; - ++q; - } - else if ( (_flags & NEEDS_ENTITY_PROCESSING) && *p == '&' ) { - // Entities handled by tinyXML2: - // - special entities in the entity table [in/out] - // - numeric character reference [in] - // 中 or 中 - - if ( *(p+1) == '#' ) { - const int buflen = 10; - char buf[buflen] = { 0 }; - int len = 0; - const char* adjusted = const_cast( XMLUtil::GetCharacterRef( p, buf, &len ) ); - if ( adjusted == 0 ) { - *q = *p; - ++p; - ++q; - } - else { - TIXMLASSERT( 0 <= len && len <= buflen ); - TIXMLASSERT( q + len <= adjusted ); - p = adjusted; - memcpy( q, buf, len ); - q += len; - } - } - else { - bool entityFound = false; - for( int i = 0; i < NUM_ENTITIES; ++i ) { - const Entity& entity = entities[i]; - if ( strncmp( p + 1, entity.pattern, entity.length ) == 0 - && *( p + entity.length + 1 ) == ';' ) { - // Found an entity - convert. - *q = entity.value; - ++q; - p += entity.length + 2; - entityFound = true; - break; - } - } - if ( !entityFound ) { - // fixme: treat as error? - ++p; - ++q; - } - } - } - else { - *q = *p; - ++p; - ++q; - } - } - *q = 0; - } - // The loop below has plenty going on, and this - // is a less useful mode. Break it out. - if ( _flags & NEEDS_WHITESPACE_COLLAPSING ) { - CollapseWhitespace(); - } - _flags = (_flags & NEEDS_DELETE); - } - TIXMLASSERT( _start ); - return _start; -} - - - - -// --------- XMLUtil ----------- // - -const char* XMLUtil::writeBoolTrue = "true"; -const char* XMLUtil::writeBoolFalse = "false"; - -void XMLUtil::SetBoolSerialization(const char* writeTrue, const char* writeFalse) -{ - static const char* defTrue = "true"; - static const char* defFalse = "false"; - - writeBoolTrue = (writeTrue) ? writeTrue : defTrue; - writeBoolFalse = (writeFalse) ? writeFalse : defFalse; -} - - -const char* XMLUtil::ReadBOM( const char* p, bool* bom ) -{ - TIXMLASSERT( p ); - TIXMLASSERT( bom ); - *bom = false; - const unsigned char* pu = reinterpret_cast(p); - // Check for BOM: - if ( *(pu+0) == TIXML_UTF_LEAD_0 - && *(pu+1) == TIXML_UTF_LEAD_1 - && *(pu+2) == TIXML_UTF_LEAD_2 ) { - *bom = true; - p += 3; - } - TIXMLASSERT( p ); - return p; -} - - -void XMLUtil::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ) -{ - const unsigned long BYTE_MASK = 0xBF; - const unsigned long BYTE_MARK = 0x80; - const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - - if (input < 0x80) { - *length = 1; - } - else if ( input < 0x800 ) { - *length = 2; - } - else if ( input < 0x10000 ) { - *length = 3; - } - else if ( input < 0x200000 ) { - *length = 4; - } - else { - *length = 0; // This code won't convert this correctly anyway. - return; - } - - output += *length; - - // Scary scary fall throughs are annotated with carefully designed comments - // to suppress compiler warnings such as -Wimplicit-fallthrough in gcc - switch (*length) { - case 4: - --output; - *output = static_cast((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - //fall through - case 3: - --output; - *output = static_cast((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - //fall through - case 2: - --output; - *output = static_cast((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - //fall through - case 1: - --output; - *output = static_cast(input | FIRST_BYTE_MARK[*length]); - break; - default: - TIXMLASSERT( false ); - } -} - - -const char* XMLUtil::GetCharacterRef( const char* p, char* value, int* length ) -{ - // Presume an entity, and pull it out. - *length = 0; - - if ( *(p+1) == '#' && *(p+2) ) { - unsigned long ucs = 0; - TIXMLASSERT( sizeof( ucs ) >= 4 ); - ptrdiff_t delta = 0; - unsigned mult = 1; - static const char SEMICOLON = ';'; - - if ( *(p+2) == 'x' ) { - // Hexadecimal. - const char* q = p+3; - if ( !(*q) ) { - return 0; - } - - q = strchr( q, SEMICOLON ); - - if ( !q ) { - return 0; - } - TIXMLASSERT( *q == SEMICOLON ); - - delta = q-p; - --q; - - while ( *q != 'x' ) { - unsigned int digit = 0; - - if ( *q >= '0' && *q <= '9' ) { - digit = *q - '0'; - } - else if ( *q >= 'a' && *q <= 'f' ) { - digit = *q - 'a' + 10; - } - else if ( *q >= 'A' && *q <= 'F' ) { - digit = *q - 'A' + 10; - } - else { - return 0; - } - TIXMLASSERT( digit < 16 ); - TIXMLASSERT( digit == 0 || mult <= UINT_MAX / digit ); - const unsigned int digitScaled = mult * digit; - TIXMLASSERT( ucs <= ULONG_MAX - digitScaled ); - ucs += digitScaled; - TIXMLASSERT( mult <= UINT_MAX / 16 ); - mult *= 16; - --q; - } - } - else { - // Decimal. - const char* q = p+2; - if ( !(*q) ) { - return 0; - } - - q = strchr( q, SEMICOLON ); - - if ( !q ) { - return 0; - } - TIXMLASSERT( *q == SEMICOLON ); - - delta = q-p; - --q; - - while ( *q != '#' ) { - if ( *q >= '0' && *q <= '9' ) { - const unsigned int digit = *q - '0'; - TIXMLASSERT( digit < 10 ); - TIXMLASSERT( digit == 0 || mult <= UINT_MAX / digit ); - const unsigned int digitScaled = mult * digit; - TIXMLASSERT( ucs <= ULONG_MAX - digitScaled ); - ucs += digitScaled; - } - else { - return 0; - } - TIXMLASSERT( mult <= UINT_MAX / 10 ); - mult *= 10; - --q; - } - } - // convert the UCS to UTF-8 - ConvertUTF32ToUTF8( ucs, value, length ); - return p + delta + 1; - } - return p+1; -} - - -void XMLUtil::ToStr( int v, char* buffer, int bufferSize ) -{ - TIXML_SNPRINTF( buffer, bufferSize, "%d", v ); -} - - -void XMLUtil::ToStr( unsigned v, char* buffer, int bufferSize ) -{ - TIXML_SNPRINTF( buffer, bufferSize, "%u", v ); -} - - -void XMLUtil::ToStr( bool v, char* buffer, int bufferSize ) -{ - TIXML_SNPRINTF( buffer, bufferSize, "%s", v ? writeBoolTrue : writeBoolFalse); -} - -/* - ToStr() of a number is a very tricky topic. - https://github.com/leethomason/tinyxml2/issues/106 -*/ -void XMLUtil::ToStr( float v, char* buffer, int bufferSize ) -{ - TIXML_SNPRINTF( buffer, bufferSize, "%.8g", v ); -} - - -void XMLUtil::ToStr( double v, char* buffer, int bufferSize ) -{ - TIXML_SNPRINTF( buffer, bufferSize, "%.17g", v ); -} - - -void XMLUtil::ToStr( int64_t v, char* buffer, int bufferSize ) -{ - // horrible syntax trick to make the compiler happy about %lld - TIXML_SNPRINTF(buffer, bufferSize, "%lld", static_cast(v)); -} - -void XMLUtil::ToStr( uint64_t v, char* buffer, int bufferSize ) -{ - // horrible syntax trick to make the compiler happy about %llu - TIXML_SNPRINTF(buffer, bufferSize, "%llu", (long long)v); -} - -bool XMLUtil::ToInt(const char* str, int* value) -{ - if (IsPrefixHex(str)) { - unsigned v; - if (TIXML_SSCANF(str, "%x", &v) == 1) { - *value = static_cast(v); - return true; - } - } - else { - if (TIXML_SSCANF(str, "%d", value) == 1) { - return true; - } - } - return false; -} - -bool XMLUtil::ToUnsigned(const char* str, unsigned* value) -{ - if (TIXML_SSCANF(str, IsPrefixHex(str) ? "%x" : "%u", value) == 1) { - return true; - } - return false; -} - -bool XMLUtil::ToBool( const char* str, bool* value ) -{ - int ival = 0; - if ( ToInt( str, &ival )) { - *value = (ival==0) ? false : true; - return true; - } - static const char* TRUE_VALS[] = { "true", "True", "TRUE", 0 }; - static const char* FALSE_VALS[] = { "false", "False", "FALSE", 0 }; - - for (int i = 0; TRUE_VALS[i]; ++i) { - if (StringEqual(str, TRUE_VALS[i])) { - *value = true; - return true; - } - } - for (int i = 0; FALSE_VALS[i]; ++i) { - if (StringEqual(str, FALSE_VALS[i])) { - *value = false; - return true; - } - } - return false; -} - - -bool XMLUtil::ToFloat( const char* str, float* value ) -{ - if ( TIXML_SSCANF( str, "%f", value ) == 1 ) { - return true; - } - return false; -} - - -bool XMLUtil::ToDouble( const char* str, double* value ) -{ - if ( TIXML_SSCANF( str, "%lf", value ) == 1 ) { - return true; - } - return false; -} - - -bool XMLUtil::ToInt64(const char* str, int64_t* value) -{ - if (IsPrefixHex(str)) { - unsigned long long v = 0; // horrible syntax trick to make the compiler happy about %llx - if (TIXML_SSCANF(str, "%llx", &v) == 1) { - *value = static_cast(v); - return true; - } - } - else { - long long v = 0; // horrible syntax trick to make the compiler happy about %lld - if (TIXML_SSCANF(str, "%lld", &v) == 1) { - *value = static_cast(v); - return true; - } - } - return false; -} - - -bool XMLUtil::ToUnsigned64(const char* str, uint64_t* value) { - unsigned long long v = 0; // horrible syntax trick to make the compiler happy about %llu - if(TIXML_SSCANF(str, IsPrefixHex(str) ? "%llx" : "%llu", &v) == 1) { - *value = (uint64_t)v; - return true; - } - return false; -} - - -char* XMLDocument::Identify( char* p, XMLNode** node ) -{ - TIXMLASSERT( node ); - TIXMLASSERT( p ); - char* const start = p; - int const startLine = _parseCurLineNum; - p = XMLUtil::SkipWhiteSpace( p, &_parseCurLineNum ); - if( !*p ) { - *node = 0; - TIXMLASSERT( p ); - return p; - } - - // These strings define the matching patterns: - static const char* xmlHeader = { "( _commentPool ); - returnNode->_parseLineNum = _parseCurLineNum; - p += xmlHeaderLen; - } - else if ( XMLUtil::StringEqual( p, commentHeader, commentHeaderLen ) ) { - returnNode = CreateUnlinkedNode( _commentPool ); - returnNode->_parseLineNum = _parseCurLineNum; - p += commentHeaderLen; - } - else if ( XMLUtil::StringEqual( p, cdataHeader, cdataHeaderLen ) ) { - XMLText* text = CreateUnlinkedNode( _textPool ); - returnNode = text; - returnNode->_parseLineNum = _parseCurLineNum; - p += cdataHeaderLen; - text->SetCData( true ); - } - else if ( XMLUtil::StringEqual( p, dtdHeader, dtdHeaderLen ) ) { - returnNode = CreateUnlinkedNode( _commentPool ); - returnNode->_parseLineNum = _parseCurLineNum; - p += dtdHeaderLen; - } - else if ( XMLUtil::StringEqual( p, elementHeader, elementHeaderLen ) ) { - returnNode = CreateUnlinkedNode( _elementPool ); - returnNode->_parseLineNum = _parseCurLineNum; - p += elementHeaderLen; - } - else { - returnNode = CreateUnlinkedNode( _textPool ); - returnNode->_parseLineNum = _parseCurLineNum; // Report line of first non-whitespace character - p = start; // Back it up, all the text counts. - _parseCurLineNum = startLine; - } - - TIXMLASSERT( returnNode ); - TIXMLASSERT( p ); - *node = returnNode; - return p; -} - - -bool XMLDocument::Accept( XMLVisitor* visitor ) const -{ - TIXMLASSERT( visitor ); - if ( visitor->VisitEnter( *this ) ) { - for ( const XMLNode* node=FirstChild(); node; node=node->NextSibling() ) { - if ( !node->Accept( visitor ) ) { - break; - } - } - } - return visitor->VisitExit( *this ); -} - - -// --------- XMLNode ----------- // - -XMLNode::XMLNode( XMLDocument* doc ) : - _document( doc ), - _parent( 0 ), - _value(), - _parseLineNum( 0 ), - _firstChild( 0 ), _lastChild( 0 ), - _prev( 0 ), _next( 0 ), - _userData( 0 ), - _memPool( 0 ) -{ -} - - -XMLNode::~XMLNode() -{ - DeleteChildren(); - if ( _parent ) { - _parent->Unlink( this ); - } -} - -const char* XMLNode::Value() const -{ - // Edge case: XMLDocuments don't have a Value. Return null. - if ( this->ToDocument() ) - return 0; - return _value.GetStr(); -} - -void XMLNode::SetValue( const char* str, bool staticMem ) -{ - if ( staticMem ) { - _value.SetInternedStr( str ); - } - else { - _value.SetStr( str ); - } -} - -XMLNode* XMLNode::DeepClone(XMLDocument* target) const -{ - XMLNode* clone = this->ShallowClone(target); - if (!clone) return 0; - - for (const XMLNode* child = this->FirstChild(); child; child = child->NextSibling()) { - XMLNode* childClone = child->DeepClone(target); - TIXMLASSERT(childClone); - clone->InsertEndChild(childClone); - } - return clone; -} - -void XMLNode::DeleteChildren() -{ - while( _firstChild ) { - TIXMLASSERT( _lastChild ); - DeleteChild( _firstChild ); - } - _firstChild = _lastChild = 0; -} - - -void XMLNode::Unlink( XMLNode* child ) -{ - TIXMLASSERT( child ); - TIXMLASSERT( child->_document == _document ); - TIXMLASSERT( child->_parent == this ); - if ( child == _firstChild ) { - _firstChild = _firstChild->_next; - } - if ( child == _lastChild ) { - _lastChild = _lastChild->_prev; - } - - if ( child->_prev ) { - child->_prev->_next = child->_next; - } - if ( child->_next ) { - child->_next->_prev = child->_prev; - } - child->_next = 0; - child->_prev = 0; - child->_parent = 0; -} - - -void XMLNode::DeleteChild( XMLNode* node ) -{ - TIXMLASSERT( node ); - TIXMLASSERT( node->_document == _document ); - TIXMLASSERT( node->_parent == this ); - Unlink( node ); - TIXMLASSERT(node->_prev == 0); - TIXMLASSERT(node->_next == 0); - TIXMLASSERT(node->_parent == 0); - DeleteNode( node ); -} - - -XMLNode* XMLNode::InsertEndChild( XMLNode* addThis ) -{ - TIXMLASSERT( addThis ); - if ( addThis->_document != _document ) { - TIXMLASSERT( false ); - return 0; - } - InsertChildPreamble( addThis ); - - if ( _lastChild ) { - TIXMLASSERT( _firstChild ); - TIXMLASSERT( _lastChild->_next == 0 ); - _lastChild->_next = addThis; - addThis->_prev = _lastChild; - _lastChild = addThis; - - addThis->_next = 0; - } - else { - TIXMLASSERT( _firstChild == 0 ); - _firstChild = _lastChild = addThis; - - addThis->_prev = 0; - addThis->_next = 0; - } - addThis->_parent = this; - return addThis; -} - - -XMLNode* XMLNode::InsertFirstChild( XMLNode* addThis ) -{ - TIXMLASSERT( addThis ); - if ( addThis->_document != _document ) { - TIXMLASSERT( false ); - return 0; - } - InsertChildPreamble( addThis ); - - if ( _firstChild ) { - TIXMLASSERT( _lastChild ); - TIXMLASSERT( _firstChild->_prev == 0 ); - - _firstChild->_prev = addThis; - addThis->_next = _firstChild; - _firstChild = addThis; - - addThis->_prev = 0; - } - else { - TIXMLASSERT( _lastChild == 0 ); - _firstChild = _lastChild = addThis; - - addThis->_prev = 0; - addThis->_next = 0; - } - addThis->_parent = this; - return addThis; -} - - -XMLNode* XMLNode::InsertAfterChild( XMLNode* afterThis, XMLNode* addThis ) -{ - TIXMLASSERT( addThis ); - if ( addThis->_document != _document ) { - TIXMLASSERT( false ); - return 0; - } - - TIXMLASSERT( afterThis ); - - if ( afterThis->_parent != this ) { - TIXMLASSERT( false ); - return 0; - } - if ( afterThis == addThis ) { - // Current state: BeforeThis -> AddThis -> OneAfterAddThis - // Now AddThis must disappear from it's location and then - // reappear between BeforeThis and OneAfterAddThis. - // So just leave it where it is. - return addThis; - } - - if ( afterThis->_next == 0 ) { - // The last node or the only node. - return InsertEndChild( addThis ); - } - InsertChildPreamble( addThis ); - addThis->_prev = afterThis; - addThis->_next = afterThis->_next; - afterThis->_next->_prev = addThis; - afterThis->_next = addThis; - addThis->_parent = this; - return addThis; -} - - - - -const XMLElement* XMLNode::FirstChildElement( const char* name ) const -{ - for( const XMLNode* node = _firstChild; node; node = node->_next ) { - const XMLElement* element = node->ToElementWithName( name ); - if ( element ) { - return element; - } - } - return 0; -} - - -const XMLElement* XMLNode::LastChildElement( const char* name ) const -{ - for( const XMLNode* node = _lastChild; node; node = node->_prev ) { - const XMLElement* element = node->ToElementWithName( name ); - if ( element ) { - return element; - } - } - return 0; -} - - -const XMLElement* XMLNode::NextSiblingElement( const char* name ) const -{ - for( const XMLNode* node = _next; node; node = node->_next ) { - const XMLElement* element = node->ToElementWithName( name ); - if ( element ) { - return element; - } - } - return 0; -} - - -const XMLElement* XMLNode::PreviousSiblingElement( const char* name ) const -{ - for( const XMLNode* node = _prev; node; node = node->_prev ) { - const XMLElement* element = node->ToElementWithName( name ); - if ( element ) { - return element; - } - } - return 0; -} - - -char* XMLNode::ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ) -{ - // This is a recursive method, but thinking about it "at the current level" - // it is a pretty simple flat list: - // - // - // - // With a special case: - // - // - // - // - // Where the closing element (/foo) *must* be the next thing after the opening - // element, and the names must match. BUT the tricky bit is that the closing - // element will be read by the child. - // - // 'endTag' is the end tag for this node, it is returned by a call to a child. - // 'parentEnd' is the end tag for the parent, which is filled in and returned. - - XMLDocument::DepthTracker tracker(_document); - if (_document->Error()) - return 0; - - while( p && *p ) { - XMLNode* node = 0; - - p = _document->Identify( p, &node ); - TIXMLASSERT( p ); - if ( node == 0 ) { - break; - } - - const int initialLineNum = node->_parseLineNum; - - StrPair endTag; - p = node->ParseDeep( p, &endTag, curLineNumPtr ); - if ( !p ) { - DeleteNode( node ); - if ( !_document->Error() ) { - _document->SetError( XML_ERROR_PARSING, initialLineNum, 0); - } - break; - } - - const XMLDeclaration* const decl = node->ToDeclaration(); - if ( decl ) { - // Declarations are only allowed at document level - // - // Multiple declarations are allowed but all declarations - // must occur before anything else. - // - // Optimized due to a security test case. If the first node is - // a declaration, and the last node is a declaration, then only - // declarations have so far been added. - bool wellLocated = false; - - if (ToDocument()) { - if (FirstChild()) { - wellLocated = - FirstChild() && - FirstChild()->ToDeclaration() && - LastChild() && - LastChild()->ToDeclaration(); - } - else { - wellLocated = true; - } - } - if ( !wellLocated ) { - _document->SetError( XML_ERROR_PARSING_DECLARATION, initialLineNum, "XMLDeclaration value=%s", decl->Value()); - DeleteNode( node ); - break; - } - } - - XMLElement* ele = node->ToElement(); - if ( ele ) { - // We read the end tag. Return it to the parent. - if ( ele->ClosingType() == XMLElement::CLOSING ) { - if ( parentEndTag ) { - ele->_value.TransferTo( parentEndTag ); - } - node->_memPool->SetTracked(); // created and then immediately deleted. - DeleteNode( node ); - return p; - } - - // Handle an end tag returned to this level. - // And handle a bunch of annoying errors. - bool mismatch = false; - if ( endTag.Empty() ) { - if ( ele->ClosingType() == XMLElement::OPEN ) { - mismatch = true; - } - } - else { - if ( ele->ClosingType() != XMLElement::OPEN ) { - mismatch = true; - } - else if ( !XMLUtil::StringEqual( endTag.GetStr(), ele->Name() ) ) { - mismatch = true; - } - } - if ( mismatch ) { - _document->SetError( XML_ERROR_MISMATCHED_ELEMENT, initialLineNum, "XMLElement name=%s", ele->Name()); - DeleteNode( node ); - break; - } - } - InsertEndChild( node ); - } - return 0; -} - -/*static*/ void XMLNode::DeleteNode( XMLNode* node ) -{ - if ( node == 0 ) { - return; - } - TIXMLASSERT(node->_document); - if (!node->ToDocument()) { - node->_document->MarkInUse(node); - } - - MemPool* pool = node->_memPool; - node->~XMLNode(); - pool->Free( node ); -} - -void XMLNode::InsertChildPreamble( XMLNode* insertThis ) const -{ - TIXMLASSERT( insertThis ); - TIXMLASSERT( insertThis->_document == _document ); - - if (insertThis->_parent) { - insertThis->_parent->Unlink( insertThis ); - } - else { - insertThis->_document->MarkInUse(insertThis); - insertThis->_memPool->SetTracked(); - } -} - -const XMLElement* XMLNode::ToElementWithName( const char* name ) const -{ - const XMLElement* element = this->ToElement(); - if ( element == 0 ) { - return 0; - } - if ( name == 0 ) { - return element; - } - if ( XMLUtil::StringEqual( element->Name(), name ) ) { - return element; - } - return 0; -} - -// --------- XMLText ---------- // -char* XMLText::ParseDeep( char* p, StrPair*, int* curLineNumPtr ) -{ - if ( this->CData() ) { - p = _value.ParseText( p, "]]>", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr ); - if ( !p ) { - _document->SetError( XML_ERROR_PARSING_CDATA, _parseLineNum, 0 ); - } - return p; - } - else { - int flags = _document->ProcessEntities() ? StrPair::TEXT_ELEMENT : StrPair::TEXT_ELEMENT_LEAVE_ENTITIES; - if ( _document->WhitespaceMode() == COLLAPSE_WHITESPACE ) { - flags |= StrPair::NEEDS_WHITESPACE_COLLAPSING; - } - - p = _value.ParseText( p, "<", flags, curLineNumPtr ); - if ( p && *p ) { - return p-1; - } - if ( !p ) { - _document->SetError( XML_ERROR_PARSING_TEXT, _parseLineNum, 0 ); - } - } - return 0; -} - - -XMLNode* XMLText::ShallowClone( XMLDocument* doc ) const -{ - if ( !doc ) { - doc = _document; - } - XMLText* text = doc->NewText( Value() ); // fixme: this will always allocate memory. Intern? - text->SetCData( this->CData() ); - return text; -} - - -bool XMLText::ShallowEqual( const XMLNode* compare ) const -{ - TIXMLASSERT( compare ); - const XMLText* text = compare->ToText(); - return ( text && XMLUtil::StringEqual( text->Value(), Value() ) ); -} - - -bool XMLText::Accept( XMLVisitor* visitor ) const -{ - TIXMLASSERT( visitor ); - return visitor->Visit( *this ); -} - - -// --------- XMLComment ---------- // - -XMLComment::XMLComment( XMLDocument* doc ) : XMLNode( doc ) -{ -} - - -XMLComment::~XMLComment() -{ -} - - -char* XMLComment::ParseDeep( char* p, StrPair*, int* curLineNumPtr ) -{ - // Comment parses as text. - p = _value.ParseText( p, "-->", StrPair::COMMENT, curLineNumPtr ); - if ( p == 0 ) { - _document->SetError( XML_ERROR_PARSING_COMMENT, _parseLineNum, 0 ); - } - return p; -} - - -XMLNode* XMLComment::ShallowClone( XMLDocument* doc ) const -{ - if ( !doc ) { - doc = _document; - } - XMLComment* comment = doc->NewComment( Value() ); // fixme: this will always allocate memory. Intern? - return comment; -} - - -bool XMLComment::ShallowEqual( const XMLNode* compare ) const -{ - TIXMLASSERT( compare ); - const XMLComment* comment = compare->ToComment(); - return ( comment && XMLUtil::StringEqual( comment->Value(), Value() )); -} - - -bool XMLComment::Accept( XMLVisitor* visitor ) const -{ - TIXMLASSERT( visitor ); - return visitor->Visit( *this ); -} - - -// --------- XMLDeclaration ---------- // - -XMLDeclaration::XMLDeclaration( XMLDocument* doc ) : XMLNode( doc ) -{ -} - - -XMLDeclaration::~XMLDeclaration() -{ - //printf( "~XMLDeclaration\n" ); -} - - -char* XMLDeclaration::ParseDeep( char* p, StrPair*, int* curLineNumPtr ) -{ - // Declaration parses as text. - p = _value.ParseText( p, "?>", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr ); - if ( p == 0 ) { - _document->SetError( XML_ERROR_PARSING_DECLARATION, _parseLineNum, 0 ); - } - return p; -} - - -XMLNode* XMLDeclaration::ShallowClone( XMLDocument* doc ) const -{ - if ( !doc ) { - doc = _document; - } - XMLDeclaration* dec = doc->NewDeclaration( Value() ); // fixme: this will always allocate memory. Intern? - return dec; -} - - -bool XMLDeclaration::ShallowEqual( const XMLNode* compare ) const -{ - TIXMLASSERT( compare ); - const XMLDeclaration* declaration = compare->ToDeclaration(); - return ( declaration && XMLUtil::StringEqual( declaration->Value(), Value() )); -} - - - -bool XMLDeclaration::Accept( XMLVisitor* visitor ) const -{ - TIXMLASSERT( visitor ); - return visitor->Visit( *this ); -} - -// --------- XMLUnknown ---------- // - -XMLUnknown::XMLUnknown( XMLDocument* doc ) : XMLNode( doc ) -{ -} - - -XMLUnknown::~XMLUnknown() -{ -} - - -char* XMLUnknown::ParseDeep( char* p, StrPair*, int* curLineNumPtr ) -{ - // Unknown parses as text. - p = _value.ParseText( p, ">", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr ); - if ( !p ) { - _document->SetError( XML_ERROR_PARSING_UNKNOWN, _parseLineNum, 0 ); - } - return p; -} - - -XMLNode* XMLUnknown::ShallowClone( XMLDocument* doc ) const -{ - if ( !doc ) { - doc = _document; - } - XMLUnknown* text = doc->NewUnknown( Value() ); // fixme: this will always allocate memory. Intern? - return text; -} - - -bool XMLUnknown::ShallowEqual( const XMLNode* compare ) const -{ - TIXMLASSERT( compare ); - const XMLUnknown* unknown = compare->ToUnknown(); - return ( unknown && XMLUtil::StringEqual( unknown->Value(), Value() )); -} - - -bool XMLUnknown::Accept( XMLVisitor* visitor ) const -{ - TIXMLASSERT( visitor ); - return visitor->Visit( *this ); -} - -// --------- XMLAttribute ---------- // - -const char* XMLAttribute::Name() const -{ - return _name.GetStr(); -} - -const char* XMLAttribute::Value() const -{ - return _value.GetStr(); -} - -char* XMLAttribute::ParseDeep( char* p, bool processEntities, int* curLineNumPtr ) -{ - // Parse using the name rules: bug fix, was using ParseText before - p = _name.ParseName( p ); - if ( !p || !*p ) { - return 0; - } - - // Skip white space before = - p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr ); - if ( *p != '=' ) { - return 0; - } - - ++p; // move up to opening quote - p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr ); - if ( *p != '\"' && *p != '\'' ) { - return 0; - } - - const char endTag[2] = { *p, 0 }; - ++p; // move past opening quote - - p = _value.ParseText( p, endTag, processEntities ? StrPair::ATTRIBUTE_VALUE : StrPair::ATTRIBUTE_VALUE_LEAVE_ENTITIES, curLineNumPtr ); - return p; -} - - -void XMLAttribute::SetName( const char* n ) -{ - _name.SetStr( n ); -} - - -XMLError XMLAttribute::QueryIntValue( int* value ) const -{ - if ( XMLUtil::ToInt( Value(), value )) { - return XML_SUCCESS; - } - return XML_WRONG_ATTRIBUTE_TYPE; -} - - -XMLError XMLAttribute::QueryUnsignedValue( unsigned int* value ) const -{ - if ( XMLUtil::ToUnsigned( Value(), value )) { - return XML_SUCCESS; - } - return XML_WRONG_ATTRIBUTE_TYPE; -} - - -XMLError XMLAttribute::QueryInt64Value(int64_t* value) const -{ - if (XMLUtil::ToInt64(Value(), value)) { - return XML_SUCCESS; - } - return XML_WRONG_ATTRIBUTE_TYPE; -} - - -XMLError XMLAttribute::QueryUnsigned64Value(uint64_t* value) const -{ - if(XMLUtil::ToUnsigned64(Value(), value)) { - return XML_SUCCESS; - } - return XML_WRONG_ATTRIBUTE_TYPE; -} - - -XMLError XMLAttribute::QueryBoolValue( bool* value ) const -{ - if ( XMLUtil::ToBool( Value(), value )) { - return XML_SUCCESS; - } - return XML_WRONG_ATTRIBUTE_TYPE; -} - - -XMLError XMLAttribute::QueryFloatValue( float* value ) const -{ - if ( XMLUtil::ToFloat( Value(), value )) { - return XML_SUCCESS; - } - return XML_WRONG_ATTRIBUTE_TYPE; -} - - -XMLError XMLAttribute::QueryDoubleValue( double* value ) const -{ - if ( XMLUtil::ToDouble( Value(), value )) { - return XML_SUCCESS; - } - return XML_WRONG_ATTRIBUTE_TYPE; -} - - -void XMLAttribute::SetAttribute( const char* v ) -{ - _value.SetStr( v ); -} - - -void XMLAttribute::SetAttribute( int v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - _value.SetStr( buf ); -} - - -void XMLAttribute::SetAttribute( unsigned v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - _value.SetStr( buf ); -} - - -void XMLAttribute::SetAttribute(int64_t v) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr(v, buf, BUF_SIZE); - _value.SetStr(buf); -} - -void XMLAttribute::SetAttribute(uint64_t v) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr(v, buf, BUF_SIZE); - _value.SetStr(buf); -} - - -void XMLAttribute::SetAttribute( bool v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - _value.SetStr( buf ); -} - -void XMLAttribute::SetAttribute( double v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - _value.SetStr( buf ); -} - -void XMLAttribute::SetAttribute( float v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - _value.SetStr( buf ); -} - - -// --------- XMLElement ---------- // -XMLElement::XMLElement( XMLDocument* doc ) : XMLNode( doc ), - _closingType( OPEN ), - _rootAttribute( 0 ) -{ -} - - -XMLElement::~XMLElement() -{ - while( _rootAttribute ) { - XMLAttribute* next = _rootAttribute->_next; - DeleteAttribute( _rootAttribute ); - _rootAttribute = next; - } -} - - -const XMLAttribute* XMLElement::FindAttribute( const char* name ) const -{ - for( XMLAttribute* a = _rootAttribute; a; a = a->_next ) { - if ( XMLUtil::StringEqual( a->Name(), name ) ) { - return a; - } - } - return 0; -} - - -const char* XMLElement::Attribute( const char* name, const char* value ) const -{ - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return 0; - } - if ( !value || XMLUtil::StringEqual( a->Value(), value )) { - return a->Value(); - } - return 0; -} - -int XMLElement::IntAttribute(const char* name, int defaultValue) const -{ - int i = defaultValue; - QueryIntAttribute(name, &i); - return i; -} - -unsigned XMLElement::UnsignedAttribute(const char* name, unsigned defaultValue) const -{ - unsigned i = defaultValue; - QueryUnsignedAttribute(name, &i); - return i; -} - -int64_t XMLElement::Int64Attribute(const char* name, int64_t defaultValue) const -{ - int64_t i = defaultValue; - QueryInt64Attribute(name, &i); - return i; -} - -uint64_t XMLElement::Unsigned64Attribute(const char* name, uint64_t defaultValue) const -{ - uint64_t i = defaultValue; - QueryUnsigned64Attribute(name, &i); - return i; -} - -bool XMLElement::BoolAttribute(const char* name, bool defaultValue) const -{ - bool b = defaultValue; - QueryBoolAttribute(name, &b); - return b; -} - -double XMLElement::DoubleAttribute(const char* name, double defaultValue) const -{ - double d = defaultValue; - QueryDoubleAttribute(name, &d); - return d; -} - -float XMLElement::FloatAttribute(const char* name, float defaultValue) const -{ - float f = defaultValue; - QueryFloatAttribute(name, &f); - return f; -} - -const char* XMLElement::GetText() const -{ - /* skip comment node */ - const XMLNode* node = FirstChild(); - while (node) { - if (node->ToComment()) { - node = node->NextSibling(); - continue; - } - break; - } - - if ( node && node->ToText() ) { - return node->Value(); - } - return 0; -} - - -void XMLElement::SetText( const char* inText ) -{ - if ( FirstChild() && FirstChild()->ToText() ) - FirstChild()->SetValue( inText ); - else { - XMLText* theText = GetDocument()->NewText( inText ); - InsertFirstChild( theText ); - } -} - - -void XMLElement::SetText( int v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - SetText( buf ); -} - - -void XMLElement::SetText( unsigned v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - SetText( buf ); -} - - -void XMLElement::SetText(int64_t v) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr(v, buf, BUF_SIZE); - SetText(buf); -} - -void XMLElement::SetText(uint64_t v) { - char buf[BUF_SIZE]; - XMLUtil::ToStr(v, buf, BUF_SIZE); - SetText(buf); -} - - -void XMLElement::SetText( bool v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - SetText( buf ); -} - - -void XMLElement::SetText( float v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - SetText( buf ); -} - - -void XMLElement::SetText( double v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - SetText( buf ); -} - - -XMLError XMLElement::QueryIntText( int* ival ) const -{ - if ( FirstChild() && FirstChild()->ToText() ) { - const char* t = FirstChild()->Value(); - if ( XMLUtil::ToInt( t, ival ) ) { - return XML_SUCCESS; - } - return XML_CAN_NOT_CONVERT_TEXT; - } - return XML_NO_TEXT_NODE; -} - - -XMLError XMLElement::QueryUnsignedText( unsigned* uval ) const -{ - if ( FirstChild() && FirstChild()->ToText() ) { - const char* t = FirstChild()->Value(); - if ( XMLUtil::ToUnsigned( t, uval ) ) { - return XML_SUCCESS; - } - return XML_CAN_NOT_CONVERT_TEXT; - } - return XML_NO_TEXT_NODE; -} - - -XMLError XMLElement::QueryInt64Text(int64_t* ival) const -{ - if (FirstChild() && FirstChild()->ToText()) { - const char* t = FirstChild()->Value(); - if (XMLUtil::ToInt64(t, ival)) { - return XML_SUCCESS; - } - return XML_CAN_NOT_CONVERT_TEXT; - } - return XML_NO_TEXT_NODE; -} - - -XMLError XMLElement::QueryUnsigned64Text(uint64_t* ival) const -{ - if(FirstChild() && FirstChild()->ToText()) { - const char* t = FirstChild()->Value(); - if(XMLUtil::ToUnsigned64(t, ival)) { - return XML_SUCCESS; - } - return XML_CAN_NOT_CONVERT_TEXT; - } - return XML_NO_TEXT_NODE; -} - - -XMLError XMLElement::QueryBoolText( bool* bval ) const -{ - if ( FirstChild() && FirstChild()->ToText() ) { - const char* t = FirstChild()->Value(); - if ( XMLUtil::ToBool( t, bval ) ) { - return XML_SUCCESS; - } - return XML_CAN_NOT_CONVERT_TEXT; - } - return XML_NO_TEXT_NODE; -} - - -XMLError XMLElement::QueryDoubleText( double* dval ) const -{ - if ( FirstChild() && FirstChild()->ToText() ) { - const char* t = FirstChild()->Value(); - if ( XMLUtil::ToDouble( t, dval ) ) { - return XML_SUCCESS; - } - return XML_CAN_NOT_CONVERT_TEXT; - } - return XML_NO_TEXT_NODE; -} - - -XMLError XMLElement::QueryFloatText( float* fval ) const -{ - if ( FirstChild() && FirstChild()->ToText() ) { - const char* t = FirstChild()->Value(); - if ( XMLUtil::ToFloat( t, fval ) ) { - return XML_SUCCESS; - } - return XML_CAN_NOT_CONVERT_TEXT; - } - return XML_NO_TEXT_NODE; -} - -int XMLElement::IntText(int defaultValue) const -{ - int i = defaultValue; - QueryIntText(&i); - return i; -} - -unsigned XMLElement::UnsignedText(unsigned defaultValue) const -{ - unsigned i = defaultValue; - QueryUnsignedText(&i); - return i; -} - -int64_t XMLElement::Int64Text(int64_t defaultValue) const -{ - int64_t i = defaultValue; - QueryInt64Text(&i); - return i; -} - -uint64_t XMLElement::Unsigned64Text(uint64_t defaultValue) const -{ - uint64_t i = defaultValue; - QueryUnsigned64Text(&i); - return i; -} - -bool XMLElement::BoolText(bool defaultValue) const -{ - bool b = defaultValue; - QueryBoolText(&b); - return b; -} - -double XMLElement::DoubleText(double defaultValue) const -{ - double d = defaultValue; - QueryDoubleText(&d); - return d; -} - -float XMLElement::FloatText(float defaultValue) const -{ - float f = defaultValue; - QueryFloatText(&f); - return f; -} - - -XMLAttribute* XMLElement::FindOrCreateAttribute( const char* name ) -{ - XMLAttribute* last = 0; - XMLAttribute* attrib = 0; - for( attrib = _rootAttribute; - attrib; - last = attrib, attrib = attrib->_next ) { - if ( XMLUtil::StringEqual( attrib->Name(), name ) ) { - break; - } - } - if ( !attrib ) { - attrib = CreateAttribute(); - TIXMLASSERT( attrib ); - if ( last ) { - TIXMLASSERT( last->_next == 0 ); - last->_next = attrib; - } - else { - TIXMLASSERT( _rootAttribute == 0 ); - _rootAttribute = attrib; - } - attrib->SetName( name ); - } - return attrib; -} - - -void XMLElement::DeleteAttribute( const char* name ) -{ - XMLAttribute* prev = 0; - for( XMLAttribute* a=_rootAttribute; a; a=a->_next ) { - if ( XMLUtil::StringEqual( name, a->Name() ) ) { - if ( prev ) { - prev->_next = a->_next; - } - else { - _rootAttribute = a->_next; - } - DeleteAttribute( a ); - break; - } - prev = a; - } -} - - -char* XMLElement::ParseAttributes( char* p, int* curLineNumPtr ) -{ - XMLAttribute* prevAttribute = 0; - - // Read the attributes. - while( p ) { - p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr ); - if ( !(*p) ) { - _document->SetError( XML_ERROR_PARSING_ELEMENT, _parseLineNum, "XMLElement name=%s", Name() ); - return 0; - } - - // attribute. - if (XMLUtil::IsNameStartChar( (unsigned char) *p ) ) { - XMLAttribute* attrib = CreateAttribute(); - TIXMLASSERT( attrib ); - attrib->_parseLineNum = _document->_parseCurLineNum; - - const int attrLineNum = attrib->_parseLineNum; - - p = attrib->ParseDeep( p, _document->ProcessEntities(), curLineNumPtr ); - if ( !p || Attribute( attrib->Name() ) ) { - DeleteAttribute( attrib ); - _document->SetError( XML_ERROR_PARSING_ATTRIBUTE, attrLineNum, "XMLElement name=%s", Name() ); - return 0; - } - // There is a minor bug here: if the attribute in the source xml - // document is duplicated, it will not be detected and the - // attribute will be doubly added. However, tracking the 'prevAttribute' - // avoids re-scanning the attribute list. Preferring performance for - // now, may reconsider in the future. - if ( prevAttribute ) { - TIXMLASSERT( prevAttribute->_next == 0 ); - prevAttribute->_next = attrib; - } - else { - TIXMLASSERT( _rootAttribute == 0 ); - _rootAttribute = attrib; - } - prevAttribute = attrib; - } - // end of the tag - else if ( *p == '>' ) { - ++p; - break; - } - // end of the tag - else if ( *p == '/' && *(p+1) == '>' ) { - _closingType = CLOSED; - return p+2; // done; sealed element. - } - else { - _document->SetError( XML_ERROR_PARSING_ELEMENT, _parseLineNum, 0 ); - return 0; - } - } - return p; -} - -void XMLElement::DeleteAttribute( XMLAttribute* attribute ) -{ - if ( attribute == 0 ) { - return; - } - MemPool* pool = attribute->_memPool; - attribute->~XMLAttribute(); - pool->Free( attribute ); -} - -XMLAttribute* XMLElement::CreateAttribute() -{ - TIXMLASSERT( sizeof( XMLAttribute ) == _document->_attributePool.ItemSize() ); - XMLAttribute* attrib = new (_document->_attributePool.Alloc() ) XMLAttribute(); - TIXMLASSERT( attrib ); - attrib->_memPool = &_document->_attributePool; - attrib->_memPool->SetTracked(); - return attrib; -} - - -XMLElement* XMLElement::InsertNewChildElement(const char* name) -{ - XMLElement* node = _document->NewElement(name); - return InsertEndChild(node) ? node : 0; -} - -XMLComment* XMLElement::InsertNewComment(const char* comment) -{ - XMLComment* node = _document->NewComment(comment); - return InsertEndChild(node) ? node : 0; -} - -XMLText* XMLElement::InsertNewText(const char* text) -{ - XMLText* node = _document->NewText(text); - return InsertEndChild(node) ? node : 0; -} - -XMLDeclaration* XMLElement::InsertNewDeclaration(const char* text) -{ - XMLDeclaration* node = _document->NewDeclaration(text); - return InsertEndChild(node) ? node : 0; -} - -XMLUnknown* XMLElement::InsertNewUnknown(const char* text) -{ - XMLUnknown* node = _document->NewUnknown(text); - return InsertEndChild(node) ? node : 0; -} - - - -// -// -// foobar -// -char* XMLElement::ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ) -{ - // Read the element name. - p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr ); - - // The closing element is the form. It is - // parsed just like a regular element then deleted from - // the DOM. - if ( *p == '/' ) { - _closingType = CLOSING; - ++p; - } - - p = _value.ParseName( p ); - if ( _value.Empty() ) { - return 0; - } - - p = ParseAttributes( p, curLineNumPtr ); - if ( !p || !*p || _closingType != OPEN ) { - return p; - } - - p = XMLNode::ParseDeep( p, parentEndTag, curLineNumPtr ); - return p; -} - - - -XMLNode* XMLElement::ShallowClone( XMLDocument* doc ) const -{ - if ( !doc ) { - doc = _document; - } - XMLElement* element = doc->NewElement( Value() ); // fixme: this will always allocate memory. Intern? - for( const XMLAttribute* a=FirstAttribute(); a; a=a->Next() ) { - element->SetAttribute( a->Name(), a->Value() ); // fixme: this will always allocate memory. Intern? - } - return element; -} - - -bool XMLElement::ShallowEqual( const XMLNode* compare ) const -{ - TIXMLASSERT( compare ); - const XMLElement* other = compare->ToElement(); - if ( other && XMLUtil::StringEqual( other->Name(), Name() )) { - - const XMLAttribute* a=FirstAttribute(); - const XMLAttribute* b=other->FirstAttribute(); - - while ( a && b ) { - if ( !XMLUtil::StringEqual( a->Value(), b->Value() ) ) { - return false; - } - a = a->Next(); - b = b->Next(); - } - if ( a || b ) { - // different count - return false; - } - return true; - } - return false; -} - - -bool XMLElement::Accept( XMLVisitor* visitor ) const -{ - TIXMLASSERT( visitor ); - if ( visitor->VisitEnter( *this, _rootAttribute ) ) { - for ( const XMLNode* node=FirstChild(); node; node=node->NextSibling() ) { - if ( !node->Accept( visitor ) ) { - break; - } - } - } - return visitor->VisitExit( *this ); -} - - -// --------- XMLDocument ----------- // - -// Warning: List must match 'enum XMLError' -const char* XMLDocument::_errorNames[XML_ERROR_COUNT] = { - "XML_SUCCESS", - "XML_NO_ATTRIBUTE", - "XML_WRONG_ATTRIBUTE_TYPE", - "XML_ERROR_FILE_NOT_FOUND", - "XML_ERROR_FILE_COULD_NOT_BE_OPENED", - "XML_ERROR_FILE_READ_ERROR", - "XML_ERROR_PARSING_ELEMENT", - "XML_ERROR_PARSING_ATTRIBUTE", - "XML_ERROR_PARSING_TEXT", - "XML_ERROR_PARSING_CDATA", - "XML_ERROR_PARSING_COMMENT", - "XML_ERROR_PARSING_DECLARATION", - "XML_ERROR_PARSING_UNKNOWN", - "XML_ERROR_EMPTY_DOCUMENT", - "XML_ERROR_MISMATCHED_ELEMENT", - "XML_ERROR_PARSING", - "XML_CAN_NOT_CONVERT_TEXT", - "XML_NO_TEXT_NODE", - "XML_ELEMENT_DEPTH_EXCEEDED" -}; - - -XMLDocument::XMLDocument( bool processEntities, Whitespace whitespaceMode ) : - XMLNode( 0 ), - _writeBOM( false ), - _processEntities( processEntities ), - _errorID(XML_SUCCESS), - _whitespaceMode( whitespaceMode ), - _errorStr(), - _errorLineNum( 0 ), - _charBuffer( 0 ), - _parseCurLineNum( 0 ), - _parsingDepth(0), - _unlinked(), - _elementPool(), - _attributePool(), - _textPool(), - _commentPool() -{ - // avoid VC++ C4355 warning about 'this' in initializer list (C4355 is off by default in VS2012+) - _document = this; -} - - -XMLDocument::~XMLDocument() -{ - Clear(); -} - - -void XMLDocument::MarkInUse(const XMLNode* const node) -{ - TIXMLASSERT(node); - TIXMLASSERT(node->_parent == 0); - - for (int i = 0; i < _unlinked.Size(); ++i) { - if (node == _unlinked[i]) { - _unlinked.SwapRemove(i); - break; - } - } -} - -void XMLDocument::Clear() -{ - DeleteChildren(); - while( _unlinked.Size()) { - DeleteNode(_unlinked[0]); // Will remove from _unlinked as part of delete. - } - -#ifdef TINYXML2_DEBUG - const bool hadError = Error(); -#endif - ClearError(); - - delete [] _charBuffer; - _charBuffer = 0; - _parsingDepth = 0; - -#if 0 - _textPool.Trace( "text" ); - _elementPool.Trace( "element" ); - _commentPool.Trace( "comment" ); - _attributePool.Trace( "attribute" ); -#endif - -#ifdef TINYXML2_DEBUG - if ( !hadError ) { - TIXMLASSERT( _elementPool.CurrentAllocs() == _elementPool.Untracked() ); - TIXMLASSERT( _attributePool.CurrentAllocs() == _attributePool.Untracked() ); - TIXMLASSERT( _textPool.CurrentAllocs() == _textPool.Untracked() ); - TIXMLASSERT( _commentPool.CurrentAllocs() == _commentPool.Untracked() ); - } -#endif -} - - -void XMLDocument::DeepCopy(XMLDocument* target) const -{ - TIXMLASSERT(target); - if (target == this) { - return; // technically success - a no-op. - } - - target->Clear(); - for (const XMLNode* node = this->FirstChild(); node; node = node->NextSibling()) { - target->InsertEndChild(node->DeepClone(target)); - } -} - -XMLElement* XMLDocument::NewElement( const char* name ) -{ - XMLElement* ele = CreateUnlinkedNode( _elementPool ); - ele->SetName( name ); - return ele; -} - - -XMLComment* XMLDocument::NewComment( const char* str ) -{ - XMLComment* comment = CreateUnlinkedNode( _commentPool ); - comment->SetValue( str ); - return comment; -} - - -XMLText* XMLDocument::NewText( const char* str ) -{ - XMLText* text = CreateUnlinkedNode( _textPool ); - text->SetValue( str ); - return text; -} - - -XMLDeclaration* XMLDocument::NewDeclaration( const char* str ) -{ - XMLDeclaration* dec = CreateUnlinkedNode( _commentPool ); - dec->SetValue( str ? str : "xml version=\"1.0\" encoding=\"UTF-8\"" ); - return dec; -} - - -XMLUnknown* XMLDocument::NewUnknown( const char* str ) -{ - XMLUnknown* unk = CreateUnlinkedNode( _commentPool ); - unk->SetValue( str ); - return unk; -} - -static FILE* callfopen( const char* filepath, const char* mode ) -{ - TIXMLASSERT( filepath ); - TIXMLASSERT( mode ); -#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) && (!defined WINCE) - FILE* fp = 0; - const errno_t err = fopen_s( &fp, filepath, mode ); - if ( err ) { - return 0; - } -#else - FILE* fp = fopen( filepath, mode ); -#endif - return fp; -} - -void XMLDocument::DeleteNode( XMLNode* node ) { - TIXMLASSERT( node ); - TIXMLASSERT(node->_document == this ); - if (node->_parent) { - node->_parent->DeleteChild( node ); - } - else { - // Isn't in the tree. - // Use the parent delete. - // Also, we need to mark it tracked: we 'know' - // it was never used. - node->_memPool->SetTracked(); - // Call the static XMLNode version: - XMLNode::DeleteNode(node); - } -} - - -XMLError XMLDocument::LoadFile( const char* filename ) -{ - if ( !filename ) { - TIXMLASSERT( false ); - SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, 0, "filename=" ); - return _errorID; - } - - Clear(); - FILE* fp = callfopen( filename, "rb" ); - if ( !fp ) { - SetError( XML_ERROR_FILE_NOT_FOUND, 0, "filename=%s", filename ); - return _errorID; - } - LoadFile( fp ); - fclose( fp ); - return _errorID; -} - -XMLError XMLDocument::LoadFile( FILE* fp ) -{ - Clear(); - - TIXML_FSEEK( fp, 0, SEEK_SET ); - if ( fgetc( fp ) == EOF && ferror( fp ) != 0 ) { - SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); - return _errorID; - } - - TIXML_FSEEK( fp, 0, SEEK_END ); - - unsigned long long filelength; - { - const long long fileLengthSigned = TIXML_FTELL( fp ); - TIXML_FSEEK( fp, 0, SEEK_SET ); - if ( fileLengthSigned == -1L ) { - SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); - return _errorID; - } - TIXMLASSERT( fileLengthSigned >= 0 ); - filelength = static_cast(fileLengthSigned); - } - - const size_t maxSizeT = static_cast(-1); - // We'll do the comparison as an unsigned long long, because that's guaranteed to be at - // least 8 bytes, even on a 32-bit platform. - if ( filelength >= static_cast(maxSizeT) ) { - // Cannot handle files which won't fit in buffer together with null terminator - SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); - return _errorID; - } - - if ( filelength == 0 ) { - SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); - return _errorID; - } - - const size_t size = static_cast(filelength); - TIXMLASSERT( _charBuffer == 0 ); - _charBuffer = new char[size+1]; - const size_t read = fread( _charBuffer, 1, size, fp ); - if ( read != size ) { - SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); - return _errorID; - } - - _charBuffer[size] = 0; - - Parse(); - return _errorID; -} - - -XMLError XMLDocument::SaveFile( const char* filename, bool compact ) -{ - if ( !filename ) { - TIXMLASSERT( false ); - SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, 0, "filename=" ); - return _errorID; - } - - FILE* fp = callfopen( filename, "w" ); - if ( !fp ) { - SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, 0, "filename=%s", filename ); - return _errorID; - } - SaveFile(fp, compact); - fclose( fp ); - return _errorID; -} - - -XMLError XMLDocument::SaveFile( FILE* fp, bool compact ) -{ - // Clear any error from the last save, otherwise it will get reported - // for *this* call. - ClearError(); - XMLPrinter stream( fp, compact ); - Print( &stream ); - return _errorID; -} - - -XMLError XMLDocument::Parse( const char* p, size_t len ) -{ - Clear(); - - if ( len == 0 || !p || !*p ) { - SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); - return _errorID; - } - if ( len == static_cast(-1) ) { - len = strlen( p ); - } - TIXMLASSERT( _charBuffer == 0 ); - _charBuffer = new char[ len+1 ]; - memcpy( _charBuffer, p, len ); - _charBuffer[len] = 0; - - Parse(); - if ( Error() ) { - // clean up now essentially dangling memory. - // and the parse fail can put objects in the - // pools that are dead and inaccessible. - DeleteChildren(); - _elementPool.Clear(); - _attributePool.Clear(); - _textPool.Clear(); - _commentPool.Clear(); - } - return _errorID; -} - - -void XMLDocument::Print( XMLPrinter* streamer ) const -{ - if ( streamer ) { - Accept( streamer ); - } - else { - XMLPrinter stdoutStreamer( stdout ); - Accept( &stdoutStreamer ); - } -} - - -void XMLDocument::ClearError() { - _errorID = XML_SUCCESS; - _errorLineNum = 0; - _errorStr.Reset(); -} - - -void XMLDocument::SetError( XMLError error, int lineNum, const char* format, ... ) -{ - TIXMLASSERT( error >= 0 && error < XML_ERROR_COUNT ); - _errorID = error; - _errorLineNum = lineNum; - _errorStr.Reset(); - - const size_t BUFFER_SIZE = 1000; - char* buffer = new char[BUFFER_SIZE]; - - TIXMLASSERT(sizeof(error) <= sizeof(int)); - TIXML_SNPRINTF(buffer, BUFFER_SIZE, "Error=%s ErrorID=%d (0x%x) Line number=%d", ErrorIDToName(error), int(error), int(error), lineNum); - - if (format) { - size_t len = strlen(buffer); - TIXML_SNPRINTF(buffer + len, BUFFER_SIZE - len, ": "); - len = strlen(buffer); - - va_list va; - va_start(va, format); - TIXML_VSNPRINTF(buffer + len, BUFFER_SIZE - len, format, va); - va_end(va); - } - _errorStr.SetStr(buffer); - delete[] buffer; -} - - -/*static*/ const char* XMLDocument::ErrorIDToName(XMLError errorID) -{ - TIXMLASSERT( errorID >= 0 && errorID < XML_ERROR_COUNT ); - const char* errorName = _errorNames[errorID]; - TIXMLASSERT( errorName && errorName[0] ); - return errorName; -} - -const char* XMLDocument::ErrorStr() const -{ - return _errorStr.Empty() ? "" : _errorStr.GetStr(); -} - - -void XMLDocument::PrintError() const -{ - printf("%s\n", ErrorStr()); -} - -const char* XMLDocument::ErrorName() const -{ - return ErrorIDToName(_errorID); -} - -void XMLDocument::Parse() -{ - TIXMLASSERT( NoChildren() ); // Clear() must have been called previously - TIXMLASSERT( _charBuffer ); - _parseCurLineNum = 1; - _parseLineNum = 1; - char* p = _charBuffer; - p = XMLUtil::SkipWhiteSpace( p, &_parseCurLineNum ); - p = const_cast( XMLUtil::ReadBOM( p, &_writeBOM ) ); - if ( !*p ) { - SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); - return; - } - ParseDeep(p, 0, &_parseCurLineNum ); -} - -void XMLDocument::PushDepth() -{ - _parsingDepth++; - if (_parsingDepth == TINYXML2_MAX_ELEMENT_DEPTH) { - SetError(XML_ELEMENT_DEPTH_EXCEEDED, _parseCurLineNum, "Element nesting is too deep." ); - } -} - -void XMLDocument::PopDepth() -{ - TIXMLASSERT(_parsingDepth > 0); - --_parsingDepth; -} - -XMLPrinter::XMLPrinter( FILE* file, bool compact, int depth ) : - _elementJustOpened( false ), - _stack(), - _firstElement( true ), - _fp( file ), - _depth( depth ), - _textDepth( -1 ), - _processEntities( true ), - _compactMode( compact ), - _buffer() -{ - for( int i=0; i(entityValue); - TIXMLASSERT( flagIndex < ENTITY_RANGE ); - _entityFlag[flagIndex] = true; - } - _restrictedEntityFlag[static_cast('&')] = true; - _restrictedEntityFlag[static_cast('<')] = true; - _restrictedEntityFlag[static_cast('>')] = true; // not required, but consistency is nice - _buffer.Push( 0 ); -} - - -void XMLPrinter::Print( const char* format, ... ) -{ - va_list va; - va_start( va, format ); - - if ( _fp ) { - vfprintf( _fp, format, va ); - } - else { - const int len = TIXML_VSCPRINTF( format, va ); - // Close out and re-start the va-args - va_end( va ); - TIXMLASSERT( len >= 0 ); - va_start( va, format ); - TIXMLASSERT( _buffer.Size() > 0 && _buffer[_buffer.Size() - 1] == 0 ); - char* p = _buffer.PushArr( len ) - 1; // back up over the null terminator. - TIXML_VSNPRINTF( p, len+1, format, va ); - } - va_end( va ); -} - - -void XMLPrinter::Write( const char* data, size_t size ) -{ - if ( _fp ) { - fwrite ( data , sizeof(char), size, _fp); - } - else { - char* p = _buffer.PushArr( static_cast(size) ) - 1; // back up over the null terminator. - memcpy( p, data, size ); - p[size] = 0; - } -} - - -void XMLPrinter::Putc( char ch ) -{ - if ( _fp ) { - fputc ( ch, _fp); - } - else { - char* p = _buffer.PushArr( sizeof(char) ) - 1; // back up over the null terminator. - p[0] = ch; - p[1] = 0; - } -} - - -void XMLPrinter::PrintSpace( int depth ) -{ - for( int i=0; i 0 && *q < ENTITY_RANGE ) { - // Check for entities. If one is found, flush - // the stream up until the entity, write the - // entity, and keep looking. - if ( flag[static_cast(*q)] ) { - while ( p < q ) { - const size_t delta = q - p; - const int toPrint = ( INT_MAX < delta ) ? INT_MAX : static_cast(delta); - Write( p, toPrint ); - p += toPrint; - } - bool entityPatternPrinted = false; - for( int i=0; i(delta); - Write( p, toPrint ); - } - } - else { - Write( p ); - } -} - - -void XMLPrinter::PushHeader( bool writeBOM, bool writeDec ) -{ - if ( writeBOM ) { - static const unsigned char bom[] = { TIXML_UTF_LEAD_0, TIXML_UTF_LEAD_1, TIXML_UTF_LEAD_2, 0 }; - Write( reinterpret_cast< const char* >( bom ) ); - } - if ( writeDec ) { - PushDeclaration( "xml version=\"1.0\"" ); - } -} - -void XMLPrinter::PrepareForNewNode( bool compactMode ) -{ - SealElementIfJustOpened(); - - if ( compactMode ) { - return; - } - - if ( _firstElement ) { - PrintSpace (_depth); - } else if ( _textDepth < 0) { - Putc( '\n' ); - PrintSpace( _depth ); - } - - _firstElement = false; -} - -void XMLPrinter::OpenElement( const char* name, bool compactMode ) -{ - PrepareForNewNode( compactMode ); - _stack.Push( name ); - - Write ( "<" ); - Write ( name ); - - _elementJustOpened = true; - ++_depth; -} - - -void XMLPrinter::PushAttribute( const char* name, const char* value ) -{ - TIXMLASSERT( _elementJustOpened ); - Putc ( ' ' ); - Write( name ); - Write( "=\"" ); - PrintString( value, false ); - Putc ( '\"' ); -} - - -void XMLPrinter::PushAttribute( const char* name, int v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - PushAttribute( name, buf ); -} - - -void XMLPrinter::PushAttribute( const char* name, unsigned v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - PushAttribute( name, buf ); -} - - -void XMLPrinter::PushAttribute(const char* name, int64_t v) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr(v, buf, BUF_SIZE); - PushAttribute(name, buf); -} - - -void XMLPrinter::PushAttribute(const char* name, uint64_t v) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr(v, buf, BUF_SIZE); - PushAttribute(name, buf); -} - - -void XMLPrinter::PushAttribute( const char* name, bool v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - PushAttribute( name, buf ); -} - - -void XMLPrinter::PushAttribute( const char* name, double v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - PushAttribute( name, buf ); -} - - -void XMLPrinter::CloseElement( bool compactMode ) -{ - --_depth; - const char* name = _stack.Pop(); - - if ( _elementJustOpened ) { - Write( "/>" ); - } - else { - if ( _textDepth < 0 && !compactMode) { - Putc( '\n' ); - PrintSpace( _depth ); - } - Write ( "" ); - } - - if ( _textDepth == _depth ) { - _textDepth = -1; - } - if ( _depth == 0 && !compactMode) { - Putc( '\n' ); - } - _elementJustOpened = false; -} - - -void XMLPrinter::SealElementIfJustOpened() -{ - if ( !_elementJustOpened ) { - return; - } - _elementJustOpened = false; - Putc( '>' ); -} - - -void XMLPrinter::PushText( const char* text, bool cdata ) -{ - _textDepth = _depth-1; - - SealElementIfJustOpened(); - if ( cdata ) { - Write( "" ); - } - else { - PrintString( text, true ); - } -} - - -void XMLPrinter::PushText( int64_t value ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( value, buf, BUF_SIZE ); - PushText( buf, false ); -} - - -void XMLPrinter::PushText( uint64_t value ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr(value, buf, BUF_SIZE); - PushText(buf, false); -} - - -void XMLPrinter::PushText( int value ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( value, buf, BUF_SIZE ); - PushText( buf, false ); -} - - -void XMLPrinter::PushText( unsigned value ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( value, buf, BUF_SIZE ); - PushText( buf, false ); -} - - -void XMLPrinter::PushText( bool value ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( value, buf, BUF_SIZE ); - PushText( buf, false ); -} - - -void XMLPrinter::PushText( float value ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( value, buf, BUF_SIZE ); - PushText( buf, false ); -} - - -void XMLPrinter::PushText( double value ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( value, buf, BUF_SIZE ); - PushText( buf, false ); -} - - -void XMLPrinter::PushComment( const char* comment ) -{ - PrepareForNewNode( _compactMode ); - - Write( "" ); -} - - -void XMLPrinter::PushDeclaration( const char* value ) -{ - PrepareForNewNode( _compactMode ); - - Write( "" ); -} - - -void XMLPrinter::PushUnknown( const char* value ) -{ - PrepareForNewNode( _compactMode ); - - Write( "' ); -} - - -bool XMLPrinter::VisitEnter( const XMLDocument& doc ) -{ - _processEntities = doc.ProcessEntities(); - if ( doc.HasBOM() ) { - PushHeader( true, false ); - } - return true; -} - - -bool XMLPrinter::VisitEnter( const XMLElement& element, const XMLAttribute* attribute ) -{ - const XMLElement* parentElem = 0; - if ( element.Parent() ) { - parentElem = element.Parent()->ToElement(); - } - const bool compactMode = parentElem ? CompactMode( *parentElem ) : _compactMode; - OpenElement( element.Name(), compactMode ); - while ( attribute ) { - PushAttribute( attribute->Name(), attribute->Value() ); - attribute = attribute->Next(); - } - return true; -} - - -bool XMLPrinter::VisitExit( const XMLElement& element ) -{ - CloseElement( CompactMode(element) ); - return true; -} - - -bool XMLPrinter::Visit( const XMLText& text ) -{ - PushText( text.Value(), text.CData() ); - return true; -} - - -bool XMLPrinter::Visit( const XMLComment& comment ) -{ - PushComment( comment.Value() ); - return true; -} - -bool XMLPrinter::Visit( const XMLDeclaration& declaration ) -{ - PushDeclaration( declaration.Value() ); - return true; -} - - -bool XMLPrinter::Visit( const XMLUnknown& unknown ) -{ - PushUnknown( unknown.Value() ); - return true; -} - -} // namespace tinyxml2 diff --git a/addon/tinyxml2/tinyxml2.h b/addon/tinyxml2/tinyxml2.h deleted file mode 100755 index 36f85482..00000000 --- a/addon/tinyxml2/tinyxml2.h +++ /dev/null @@ -1,2380 +0,0 @@ -/* -Original code by Lee Thomason (www.grinninglizard.com) - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must -not claim that you wrote the original software. If you use this -software in a product, an acknowledgment in the product documentation -would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. -*/ - -#ifndef TINYXML2_INCLUDED -#define TINYXML2_INCLUDED - -#if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__) -# include -# include -# include -# include -# include -# if defined(__PS3__) -# include -# endif -#else -# include -# include -# include -# include -# include -#endif -#include - -/* - TODO: intern strings instead of allocation. -*/ -/* - gcc: - g++ -Wall -DTINYXML2_DEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe - - Formatting, Artistic Style: - AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h -*/ - -#if defined( _DEBUG ) || defined (__DEBUG__) -# ifndef TINYXML2_DEBUG -# define TINYXML2_DEBUG -# endif -#endif - -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable: 4251) -#endif - -#ifdef _WIN32 -# ifdef TINYXML2_EXPORT -# define TINYXML2_LIB __declspec(dllexport) -# elif defined(TINYXML2_IMPORT) -# define TINYXML2_LIB __declspec(dllimport) -# else -# define TINYXML2_LIB -# endif -#elif __GNUC__ >= 4 -# define TINYXML2_LIB __attribute__((visibility("default"))) -#else -# define TINYXML2_LIB -#endif - - -#if !defined(TIXMLASSERT) -#if defined(TINYXML2_DEBUG) -# if defined(_MSC_VER) -# // "(void)0," is for suppressing C4127 warning in "assert(false)", "assert(true)" and the like -# define TIXMLASSERT( x ) if ( !((void)0,(x))) { __debugbreak(); } -# elif defined (ANDROID_NDK) -# include -# define TIXMLASSERT( x ) if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); } -# else -# include -# define TIXMLASSERT assert -# endif -#else -# define TIXMLASSERT( x ) {} -#endif -#endif - -/* Versioning, past 1.0.14: - http://semver.org/ -*/ -static const int TIXML2_MAJOR_VERSION = 9; -static const int TIXML2_MINOR_VERSION = 0; -static const int TIXML2_PATCH_VERSION = 0; - -#define TINYXML2_MAJOR_VERSION 9 -#define TINYXML2_MINOR_VERSION 0 -#define TINYXML2_PATCH_VERSION 0 - -// A fixed element depth limit is problematic. There needs to be a -// limit to avoid a stack overflow. However, that limit varies per -// system, and the capacity of the stack. On the other hand, it's a trivial -// attack that can result from ill, malicious, or even correctly formed XML, -// so there needs to be a limit in place. -static const int TINYXML2_MAX_ELEMENT_DEPTH = 100; - -namespace tinyxml2 -{ -class XMLDocument; -class XMLElement; -class XMLAttribute; -class XMLComment; -class XMLText; -class XMLDeclaration; -class XMLUnknown; -class XMLPrinter; - -/* - A class that wraps strings. Normally stores the start and end - pointers into the XML file itself, and will apply normalization - and entity translation if actually read. Can also store (and memory - manage) a traditional char[] - - Isn't clear why TINYXML2_LIB is needed; but seems to fix #719 -*/ -class TINYXML2_LIB StrPair -{ -public: - enum Mode { - NEEDS_ENTITY_PROCESSING = 0x01, - NEEDS_NEWLINE_NORMALIZATION = 0x02, - NEEDS_WHITESPACE_COLLAPSING = 0x04, - - TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION, - TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION, - ATTRIBUTE_NAME = 0, - ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION, - ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION, - COMMENT = NEEDS_NEWLINE_NORMALIZATION - }; - - StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {} - ~StrPair(); - - void Set( char* start, char* end, int flags ) { - TIXMLASSERT( start ); - TIXMLASSERT( end ); - Reset(); - _start = start; - _end = end; - _flags = flags | NEEDS_FLUSH; - } - - const char* GetStr(); - - bool Empty() const { - return _start == _end; - } - - void SetInternedStr( const char* str ) { - Reset(); - _start = const_cast(str); - } - - void SetStr( const char* str, int flags=0 ); - - char* ParseText( char* in, const char* endTag, int strFlags, int* curLineNumPtr ); - char* ParseName( char* in ); - - void TransferTo( StrPair* other ); - void Reset(); - -private: - void CollapseWhitespace(); - - enum { - NEEDS_FLUSH = 0x100, - NEEDS_DELETE = 0x200 - }; - - int _flags; - char* _start; - char* _end; - - StrPair( const StrPair& other ); // not supported - void operator=( const StrPair& other ); // not supported, use TransferTo() -}; - - -/* - A dynamic array of Plain Old Data. Doesn't support constructors, etc. - Has a small initial memory pool, so that low or no usage will not - cause a call to new/delete -*/ -template -class DynArray -{ -public: - DynArray() : - _mem( _pool ), - _allocated( INITIAL_SIZE ), - _size( 0 ) - { - } - - ~DynArray() { - if ( _mem != _pool ) { - delete [] _mem; - } - } - - void Clear() { - _size = 0; - } - - void Push( T t ) { - TIXMLASSERT( _size < INT_MAX ); - EnsureCapacity( _size+1 ); - _mem[_size] = t; - ++_size; - } - - T* PushArr( int count ) { - TIXMLASSERT( count >= 0 ); - TIXMLASSERT( _size <= INT_MAX - count ); - EnsureCapacity( _size+count ); - T* ret = &_mem[_size]; - _size += count; - return ret; - } - - T Pop() { - TIXMLASSERT( _size > 0 ); - --_size; - return _mem[_size]; - } - - void PopArr( int count ) { - TIXMLASSERT( _size >= count ); - _size -= count; - } - - bool Empty() const { - return _size == 0; - } - - T& operator[](int i) { - TIXMLASSERT( i>= 0 && i < _size ); - return _mem[i]; - } - - const T& operator[](int i) const { - TIXMLASSERT( i>= 0 && i < _size ); - return _mem[i]; - } - - const T& PeekTop() const { - TIXMLASSERT( _size > 0 ); - return _mem[ _size - 1]; - } - - int Size() const { - TIXMLASSERT( _size >= 0 ); - return _size; - } - - int Capacity() const { - TIXMLASSERT( _allocated >= INITIAL_SIZE ); - return _allocated; - } - - void SwapRemove(int i) { - TIXMLASSERT(i >= 0 && i < _size); - TIXMLASSERT(_size > 0); - _mem[i] = _mem[_size - 1]; - --_size; - } - - const T* Mem() const { - TIXMLASSERT( _mem ); - return _mem; - } - - T* Mem() { - TIXMLASSERT( _mem ); - return _mem; - } - -private: - DynArray( const DynArray& ); // not supported - void operator=( const DynArray& ); // not supported - - void EnsureCapacity( int cap ) { - TIXMLASSERT( cap > 0 ); - if ( cap > _allocated ) { - TIXMLASSERT( cap <= INT_MAX / 2 ); - const int newAllocated = cap * 2; - T* newMem = new T[newAllocated]; - TIXMLASSERT( newAllocated >= _size ); - memcpy( newMem, _mem, sizeof(T)*_size ); // warning: not using constructors, only works for PODs - if ( _mem != _pool ) { - delete [] _mem; - } - _mem = newMem; - _allocated = newAllocated; - } - } - - T* _mem; - T _pool[INITIAL_SIZE]; - int _allocated; // objects allocated - int _size; // number objects in use -}; - - -/* - Parent virtual class of a pool for fast allocation - and deallocation of objects. -*/ -class MemPool -{ -public: - MemPool() {} - virtual ~MemPool() {} - - virtual int ItemSize() const = 0; - virtual void* Alloc() = 0; - virtual void Free( void* ) = 0; - virtual void SetTracked() = 0; -}; - - -/* - Template child class to create pools of the correct type. -*/ -template< int ITEM_SIZE > -class MemPoolT : public MemPool -{ -public: - MemPoolT() : _blockPtrs(), _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {} - ~MemPoolT() { - MemPoolT< ITEM_SIZE >::Clear(); - } - - void Clear() { - // Delete the blocks. - while( !_blockPtrs.Empty()) { - Block* lastBlock = _blockPtrs.Pop(); - delete lastBlock; - } - _root = 0; - _currentAllocs = 0; - _nAllocs = 0; - _maxAllocs = 0; - _nUntracked = 0; - } - - virtual int ItemSize() const { - return ITEM_SIZE; - } - int CurrentAllocs() const { - return _currentAllocs; - } - - virtual void* Alloc() { - if ( !_root ) { - // Need a new block. - Block* block = new Block(); - _blockPtrs.Push( block ); - - Item* blockItems = block->items; - for( int i = 0; i < ITEMS_PER_BLOCK - 1; ++i ) { - blockItems[i].next = &(blockItems[i + 1]); - } - blockItems[ITEMS_PER_BLOCK - 1].next = 0; - _root = blockItems; - } - Item* const result = _root; - TIXMLASSERT( result != 0 ); - _root = _root->next; - - ++_currentAllocs; - if ( _currentAllocs > _maxAllocs ) { - _maxAllocs = _currentAllocs; - } - ++_nAllocs; - ++_nUntracked; - return result; - } - - virtual void Free( void* mem ) { - if ( !mem ) { - return; - } - --_currentAllocs; - Item* item = static_cast( mem ); -#ifdef TINYXML2_DEBUG - memset( item, 0xfe, sizeof( *item ) ); -#endif - item->next = _root; - _root = item; - } - void Trace( const char* name ) { - printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n", - name, _maxAllocs, _maxAllocs * ITEM_SIZE / 1024, _currentAllocs, - ITEM_SIZE, _nAllocs, _blockPtrs.Size() ); - } - - void SetTracked() { - --_nUntracked; - } - - int Untracked() const { - return _nUntracked; - } - - // This number is perf sensitive. 4k seems like a good tradeoff on my machine. - // The test file is large, 170k. - // Release: VS2010 gcc(no opt) - // 1k: 4000 - // 2k: 4000 - // 4k: 3900 21000 - // 16k: 5200 - // 32k: 4300 - // 64k: 4000 21000 - // Declared public because some compilers do not accept to use ITEMS_PER_BLOCK - // in private part if ITEMS_PER_BLOCK is private - enum { ITEMS_PER_BLOCK = (4 * 1024) / ITEM_SIZE }; - -private: - MemPoolT( const MemPoolT& ); // not supported - void operator=( const MemPoolT& ); // not supported - - union Item { - Item* next; - char itemData[ITEM_SIZE]; - }; - struct Block { - Item items[ITEMS_PER_BLOCK]; - }; - DynArray< Block*, 10 > _blockPtrs; - Item* _root; - - int _currentAllocs; - int _nAllocs; - int _maxAllocs; - int _nUntracked; -}; - - - -/** - Implements the interface to the "Visitor pattern" (see the Accept() method.) - If you call the Accept() method, it requires being passed a XMLVisitor - class to handle callbacks. For nodes that contain other nodes (Document, Element) - you will get called with a VisitEnter/VisitExit pair. Nodes that are always leafs - are simply called with Visit(). - - If you return 'true' from a Visit method, recursive parsing will continue. If you return - false, no children of this node or its siblings will be visited. - - All flavors of Visit methods have a default implementation that returns 'true' (continue - visiting). You need to only override methods that are interesting to you. - - Generally Accept() is called on the XMLDocument, although all nodes support visiting. - - You should never change the document from a callback. - - @sa XMLNode::Accept() -*/ -class TINYXML2_LIB XMLVisitor -{ -public: - virtual ~XMLVisitor() {} - - /// Visit a document. - virtual bool VisitEnter( const XMLDocument& /*doc*/ ) { - return true; - } - /// Visit a document. - virtual bool VisitExit( const XMLDocument& /*doc*/ ) { - return true; - } - - /// Visit an element. - virtual bool VisitEnter( const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/ ) { - return true; - } - /// Visit an element. - virtual bool VisitExit( const XMLElement& /*element*/ ) { - return true; - } - - /// Visit a declaration. - virtual bool Visit( const XMLDeclaration& /*declaration*/ ) { - return true; - } - /// Visit a text node. - virtual bool Visit( const XMLText& /*text*/ ) { - return true; - } - /// Visit a comment node. - virtual bool Visit( const XMLComment& /*comment*/ ) { - return true; - } - /// Visit an unknown node. - virtual bool Visit( const XMLUnknown& /*unknown*/ ) { - return true; - } -}; - -// WARNING: must match XMLDocument::_errorNames[] -enum XMLError { - XML_SUCCESS = 0, - XML_NO_ATTRIBUTE, - XML_WRONG_ATTRIBUTE_TYPE, - XML_ERROR_FILE_NOT_FOUND, - XML_ERROR_FILE_COULD_NOT_BE_OPENED, - XML_ERROR_FILE_READ_ERROR, - XML_ERROR_PARSING_ELEMENT, - XML_ERROR_PARSING_ATTRIBUTE, - XML_ERROR_PARSING_TEXT, - XML_ERROR_PARSING_CDATA, - XML_ERROR_PARSING_COMMENT, - XML_ERROR_PARSING_DECLARATION, - XML_ERROR_PARSING_UNKNOWN, - XML_ERROR_EMPTY_DOCUMENT, - XML_ERROR_MISMATCHED_ELEMENT, - XML_ERROR_PARSING, - XML_CAN_NOT_CONVERT_TEXT, - XML_NO_TEXT_NODE, - XML_ELEMENT_DEPTH_EXCEEDED, - - XML_ERROR_COUNT -}; - - -/* - Utility functionality. -*/ -class TINYXML2_LIB XMLUtil -{ -public: - static const char* SkipWhiteSpace( const char* p, int* curLineNumPtr ) { - TIXMLASSERT( p ); - - while( IsWhiteSpace(*p) ) { - if (curLineNumPtr && *p == '\n') { - ++(*curLineNumPtr); - } - ++p; - } - TIXMLASSERT( p ); - return p; - } - static char* SkipWhiteSpace( char* const p, int* curLineNumPtr ) { - return const_cast( SkipWhiteSpace( const_cast(p), curLineNumPtr ) ); - } - - // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't - // correct, but simple, and usually works. - static bool IsWhiteSpace( char p ) { - return !IsUTF8Continuation(p) && isspace( static_cast(p) ); - } - - inline static bool IsNameStartChar( unsigned char ch ) { - if ( ch >= 128 ) { - // This is a heuristic guess in attempt to not implement Unicode-aware isalpha() - return true; - } - if ( isalpha( ch ) ) { - return true; - } - return ch == ':' || ch == '_'; - } - - inline static bool IsNameChar( unsigned char ch ) { - return IsNameStartChar( ch ) - || isdigit( ch ) - || ch == '.' - || ch == '-'; - } - - inline static bool IsPrefixHex( const char* p) { - p = SkipWhiteSpace(p, 0); - return p && *p == '0' && ( *(p + 1) == 'x' || *(p + 1) == 'X'); - } - - inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX ) { - if ( p == q ) { - return true; - } - TIXMLASSERT( p ); - TIXMLASSERT( q ); - TIXMLASSERT( nChar >= 0 ); - return strncmp( p, q, nChar ) == 0; - } - - inline static bool IsUTF8Continuation( const char p ) { - return ( p & 0x80 ) != 0; - } - - static const char* ReadBOM( const char* p, bool* hasBOM ); - // p is the starting location, - // the UTF-8 value of the entity will be placed in value, and length filled in. - static const char* GetCharacterRef( const char* p, char* value, int* length ); - static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ); - - // converts primitive types to strings - static void ToStr( int v, char* buffer, int bufferSize ); - static void ToStr( unsigned v, char* buffer, int bufferSize ); - static void ToStr( bool v, char* buffer, int bufferSize ); - static void ToStr( float v, char* buffer, int bufferSize ); - static void ToStr( double v, char* buffer, int bufferSize ); - static void ToStr(int64_t v, char* buffer, int bufferSize); - static void ToStr(uint64_t v, char* buffer, int bufferSize); - - // converts strings to primitive types - static bool ToInt( const char* str, int* value ); - static bool ToUnsigned( const char* str, unsigned* value ); - static bool ToBool( const char* str, bool* value ); - static bool ToFloat( const char* str, float* value ); - static bool ToDouble( const char* str, double* value ); - static bool ToInt64(const char* str, int64_t* value); - static bool ToUnsigned64(const char* str, uint64_t* value); - // Changes what is serialized for a boolean value. - // Default to "true" and "false". Shouldn't be changed - // unless you have a special testing or compatibility need. - // Be careful: static, global, & not thread safe. - // Be sure to set static const memory as parameters. - static void SetBoolSerialization(const char* writeTrue, const char* writeFalse); - -private: - static const char* writeBoolTrue; - static const char* writeBoolFalse; -}; - - -/** XMLNode is a base class for every object that is in the - XML Document Object Model (DOM), except XMLAttributes. - Nodes have siblings, a parent, and children which can - be navigated. A node is always in a XMLDocument. - The type of a XMLNode can be queried, and it can - be cast to its more defined type. - - A XMLDocument allocates memory for all its Nodes. - When the XMLDocument gets deleted, all its Nodes - will also be deleted. - - @verbatim - A Document can contain: Element (container or leaf) - Comment (leaf) - Unknown (leaf) - Declaration( leaf ) - - An Element can contain: Element (container or leaf) - Text (leaf) - Attributes (not on tree) - Comment (leaf) - Unknown (leaf) - - @endverbatim -*/ -class TINYXML2_LIB XMLNode -{ - friend class XMLDocument; - friend class XMLElement; -public: - - /// Get the XMLDocument that owns this XMLNode. - const XMLDocument* GetDocument() const { - TIXMLASSERT( _document ); - return _document; - } - /// Get the XMLDocument that owns this XMLNode. - XMLDocument* GetDocument() { - TIXMLASSERT( _document ); - return _document; - } - - /// Safely cast to an Element, or null. - virtual XMLElement* ToElement() { - return 0; - } - /// Safely cast to Text, or null. - virtual XMLText* ToText() { - return 0; - } - /// Safely cast to a Comment, or null. - virtual XMLComment* ToComment() { - return 0; - } - /// Safely cast to a Document, or null. - virtual XMLDocument* ToDocument() { - return 0; - } - /// Safely cast to a Declaration, or null. - virtual XMLDeclaration* ToDeclaration() { - return 0; - } - /// Safely cast to an Unknown, or null. - virtual XMLUnknown* ToUnknown() { - return 0; - } - - virtual const XMLElement* ToElement() const { - return 0; - } - virtual const XMLText* ToText() const { - return 0; - } - virtual const XMLComment* ToComment() const { - return 0; - } - virtual const XMLDocument* ToDocument() const { - return 0; - } - virtual const XMLDeclaration* ToDeclaration() const { - return 0; - } - virtual const XMLUnknown* ToUnknown() const { - return 0; - } - - /** The meaning of 'value' changes for the specific type. - @verbatim - Document: empty (NULL is returned, not an empty string) - Element: name of the element - Comment: the comment text - Unknown: the tag contents - Text: the text string - @endverbatim - */ - const char* Value() const; - - /** Set the Value of an XML node. - @sa Value() - */ - void SetValue( const char* val, bool staticMem=false ); - - /// Gets the line number the node is in, if the document was parsed from a file. - int GetLineNum() const { return _parseLineNum; } - - /// Get the parent of this node on the DOM. - const XMLNode* Parent() const { - return _parent; - } - - XMLNode* Parent() { - return _parent; - } - - /// Returns true if this node has no children. - bool NoChildren() const { - return !_firstChild; - } - - /// Get the first child node, or null if none exists. - const XMLNode* FirstChild() const { - return _firstChild; - } - - XMLNode* FirstChild() { - return _firstChild; - } - - /** Get the first child element, or optionally the first child - element with the specified name. - */ - const XMLElement* FirstChildElement( const char* name = 0 ) const; - - XMLElement* FirstChildElement( const char* name = 0 ) { - return const_cast(const_cast(this)->FirstChildElement( name )); - } - - /// Get the last child node, or null if none exists. - const XMLNode* LastChild() const { - return _lastChild; - } - - XMLNode* LastChild() { - return _lastChild; - } - - /** Get the last child element or optionally the last child - element with the specified name. - */ - const XMLElement* LastChildElement( const char* name = 0 ) const; - - XMLElement* LastChildElement( const char* name = 0 ) { - return const_cast(const_cast(this)->LastChildElement(name) ); - } - - /// Get the previous (left) sibling node of this node. - const XMLNode* PreviousSibling() const { - return _prev; - } - - XMLNode* PreviousSibling() { - return _prev; - } - - /// Get the previous (left) sibling element of this node, with an optionally supplied name. - const XMLElement* PreviousSiblingElement( const char* name = 0 ) const ; - - XMLElement* PreviousSiblingElement( const char* name = 0 ) { - return const_cast(const_cast(this)->PreviousSiblingElement( name ) ); - } - - /// Get the next (right) sibling node of this node. - const XMLNode* NextSibling() const { - return _next; - } - - XMLNode* NextSibling() { - return _next; - } - - /// Get the next (right) sibling element of this node, with an optionally supplied name. - const XMLElement* NextSiblingElement( const char* name = 0 ) const; - - XMLElement* NextSiblingElement( const char* name = 0 ) { - return const_cast(const_cast(this)->NextSiblingElement( name ) ); - } - - /** - Add a child node as the last (right) child. - If the child node is already part of the document, - it is moved from its old location to the new location. - Returns the addThis argument or 0 if the node does not - belong to the same document. - */ - XMLNode* InsertEndChild( XMLNode* addThis ); - - XMLNode* LinkEndChild( XMLNode* addThis ) { - return InsertEndChild( addThis ); - } - /** - Add a child node as the first (left) child. - If the child node is already part of the document, - it is moved from its old location to the new location. - Returns the addThis argument or 0 if the node does not - belong to the same document. - */ - XMLNode* InsertFirstChild( XMLNode* addThis ); - /** - Add a node after the specified child node. - If the child node is already part of the document, - it is moved from its old location to the new location. - Returns the addThis argument or 0 if the afterThis node - is not a child of this node, or if the node does not - belong to the same document. - */ - XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis ); - - /** - Delete all the children of this node. - */ - void DeleteChildren(); - - /** - Delete a child of this node. - */ - void DeleteChild( XMLNode* node ); - - /** - Make a copy of this node, but not its children. - You may pass in a Document pointer that will be - the owner of the new Node. If the 'document' is - null, then the node returned will be allocated - from the current Document. (this->GetDocument()) - - Note: if called on a XMLDocument, this will return null. - */ - virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0; - - /** - Make a copy of this node and all its children. - - If the 'target' is null, then the nodes will - be allocated in the current document. If 'target' - is specified, the memory will be allocated is the - specified XMLDocument. - - NOTE: This is probably not the correct tool to - copy a document, since XMLDocuments can have multiple - top level XMLNodes. You probably want to use - XMLDocument::DeepCopy() - */ - XMLNode* DeepClone( XMLDocument* target ) const; - - /** - Test if 2 nodes are the same, but don't test children. - The 2 nodes do not need to be in the same Document. - - Note: if called on a XMLDocument, this will return false. - */ - virtual bool ShallowEqual( const XMLNode* compare ) const = 0; - - /** Accept a hierarchical visit of the nodes in the TinyXML-2 DOM. Every node in the - XML tree will be conditionally visited and the host will be called back - via the XMLVisitor interface. - - This is essentially a SAX interface for TinyXML-2. (Note however it doesn't re-parse - the XML for the callbacks, so the performance of TinyXML-2 is unchanged by using this - interface versus any other.) - - The interface has been based on ideas from: - - - http://www.saxproject.org/ - - http://c2.com/cgi/wiki?HierarchicalVisitorPattern - - Which are both good references for "visiting". - - An example of using Accept(): - @verbatim - XMLPrinter printer; - tinyxmlDoc.Accept( &printer ); - const char* xmlcstr = printer.CStr(); - @endverbatim - */ - virtual bool Accept( XMLVisitor* visitor ) const = 0; - - /** - Set user data into the XMLNode. TinyXML-2 in - no way processes or interprets user data. - It is initially 0. - */ - void SetUserData(void* userData) { _userData = userData; } - - /** - Get user data set into the XMLNode. TinyXML-2 in - no way processes or interprets user data. - It is initially 0. - */ - void* GetUserData() const { return _userData; } - -protected: - explicit XMLNode( XMLDocument* ); - virtual ~XMLNode(); - - virtual char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr); - - XMLDocument* _document; - XMLNode* _parent; - mutable StrPair _value; - int _parseLineNum; - - XMLNode* _firstChild; - XMLNode* _lastChild; - - XMLNode* _prev; - XMLNode* _next; - - void* _userData; - -private: - MemPool* _memPool; - void Unlink( XMLNode* child ); - static void DeleteNode( XMLNode* node ); - void InsertChildPreamble( XMLNode* insertThis ) const; - const XMLElement* ToElementWithName( const char* name ) const; - - XMLNode( const XMLNode& ); // not supported - XMLNode& operator=( const XMLNode& ); // not supported -}; - - -/** XML text. - - Note that a text node can have child element nodes, for example: - @verbatim - This is bold - @endverbatim - - A text node can have 2 ways to output the next. "normal" output - and CDATA. It will default to the mode it was parsed from the XML file and - you generally want to leave it alone, but you can change the output mode with - SetCData() and query it with CData(). -*/ -class TINYXML2_LIB XMLText : public XMLNode -{ - friend class XMLDocument; -public: - virtual bool Accept( XMLVisitor* visitor ) const; - - virtual XMLText* ToText() { - return this; - } - virtual const XMLText* ToText() const { - return this; - } - - /// Declare whether this should be CDATA or standard text. - void SetCData( bool isCData ) { - _isCData = isCData; - } - /// Returns true if this is a CDATA text element. - bool CData() const { - return _isCData; - } - - virtual XMLNode* ShallowClone( XMLDocument* document ) const; - virtual bool ShallowEqual( const XMLNode* compare ) const; - -protected: - explicit XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {} - virtual ~XMLText() {} - - char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ); - -private: - bool _isCData; - - XMLText( const XMLText& ); // not supported - XMLText& operator=( const XMLText& ); // not supported -}; - - -/** An XML Comment. */ -class TINYXML2_LIB XMLComment : public XMLNode -{ - friend class XMLDocument; -public: - virtual XMLComment* ToComment() { - return this; - } - virtual const XMLComment* ToComment() const { - return this; - } - - virtual bool Accept( XMLVisitor* visitor ) const; - - virtual XMLNode* ShallowClone( XMLDocument* document ) const; - virtual bool ShallowEqual( const XMLNode* compare ) const; - -protected: - explicit XMLComment( XMLDocument* doc ); - virtual ~XMLComment(); - - char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr); - -private: - XMLComment( const XMLComment& ); // not supported - XMLComment& operator=( const XMLComment& ); // not supported -}; - - -/** In correct XML the declaration is the first entry in the file. - @verbatim - - @endverbatim - - TinyXML-2 will happily read or write files without a declaration, - however. - - The text of the declaration isn't interpreted. It is parsed - and written as a string. -*/ -class TINYXML2_LIB XMLDeclaration : public XMLNode -{ - friend class XMLDocument; -public: - virtual XMLDeclaration* ToDeclaration() { - return this; - } - virtual const XMLDeclaration* ToDeclaration() const { - return this; - } - - virtual bool Accept( XMLVisitor* visitor ) const; - - virtual XMLNode* ShallowClone( XMLDocument* document ) const; - virtual bool ShallowEqual( const XMLNode* compare ) const; - -protected: - explicit XMLDeclaration( XMLDocument* doc ); - virtual ~XMLDeclaration(); - - char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ); - -private: - XMLDeclaration( const XMLDeclaration& ); // not supported - XMLDeclaration& operator=( const XMLDeclaration& ); // not supported -}; - - -/** Any tag that TinyXML-2 doesn't recognize is saved as an - unknown. It is a tag of text, but should not be modified. - It will be written back to the XML, unchanged, when the file - is saved. - - DTD tags get thrown into XMLUnknowns. -*/ -class TINYXML2_LIB XMLUnknown : public XMLNode -{ - friend class XMLDocument; -public: - virtual XMLUnknown* ToUnknown() { - return this; - } - virtual const XMLUnknown* ToUnknown() const { - return this; - } - - virtual bool Accept( XMLVisitor* visitor ) const; - - virtual XMLNode* ShallowClone( XMLDocument* document ) const; - virtual bool ShallowEqual( const XMLNode* compare ) const; - -protected: - explicit XMLUnknown( XMLDocument* doc ); - virtual ~XMLUnknown(); - - char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ); - -private: - XMLUnknown( const XMLUnknown& ); // not supported - XMLUnknown& operator=( const XMLUnknown& ); // not supported -}; - - - -/** An attribute is a name-value pair. Elements have an arbitrary - number of attributes, each with a unique name. - - @note The attributes are not XMLNodes. You may only query the - Next() attribute in a list. -*/ -class TINYXML2_LIB XMLAttribute -{ - friend class XMLElement; -public: - /// The name of the attribute. - const char* Name() const; - - /// The value of the attribute. - const char* Value() const; - - /// Gets the line number the attribute is in, if the document was parsed from a file. - int GetLineNum() const { return _parseLineNum; } - - /// The next attribute in the list. - const XMLAttribute* Next() const { - return _next; - } - - /** IntValue interprets the attribute as an integer, and returns the value. - If the value isn't an integer, 0 will be returned. There is no error checking; - use QueryIntValue() if you need error checking. - */ - int IntValue() const { - int i = 0; - QueryIntValue(&i); - return i; - } - - int64_t Int64Value() const { - int64_t i = 0; - QueryInt64Value(&i); - return i; - } - - uint64_t Unsigned64Value() const { - uint64_t i = 0; - QueryUnsigned64Value(&i); - return i; - } - - /// Query as an unsigned integer. See IntValue() - unsigned UnsignedValue() const { - unsigned i=0; - QueryUnsignedValue( &i ); - return i; - } - /// Query as a boolean. See IntValue() - bool BoolValue() const { - bool b=false; - QueryBoolValue( &b ); - return b; - } - /// Query as a double. See IntValue() - double DoubleValue() const { - double d=0; - QueryDoubleValue( &d ); - return d; - } - /// Query as a float. See IntValue() - float FloatValue() const { - float f=0; - QueryFloatValue( &f ); - return f; - } - - /** QueryIntValue interprets the attribute as an integer, and returns the value - in the provided parameter. The function will return XML_SUCCESS on success, - and XML_WRONG_ATTRIBUTE_TYPE if the conversion is not successful. - */ - XMLError QueryIntValue( int* value ) const; - /// See QueryIntValue - XMLError QueryUnsignedValue( unsigned int* value ) const; - /// See QueryIntValue - XMLError QueryInt64Value(int64_t* value) const; - /// See QueryIntValue - XMLError QueryUnsigned64Value(uint64_t* value) const; - /// See QueryIntValue - XMLError QueryBoolValue( bool* value ) const; - /// See QueryIntValue - XMLError QueryDoubleValue( double* value ) const; - /// See QueryIntValue - XMLError QueryFloatValue( float* value ) const; - - /// Set the attribute to a string value. - void SetAttribute( const char* value ); - /// Set the attribute to value. - void SetAttribute( int value ); - /// Set the attribute to value. - void SetAttribute( unsigned value ); - /// Set the attribute to value. - void SetAttribute(int64_t value); - /// Set the attribute to value. - void SetAttribute(uint64_t value); - /// Set the attribute to value. - void SetAttribute( bool value ); - /// Set the attribute to value. - void SetAttribute( double value ); - /// Set the attribute to value. - void SetAttribute( float value ); - -private: - enum { BUF_SIZE = 200 }; - - XMLAttribute() : _name(), _value(),_parseLineNum( 0 ), _next( 0 ), _memPool( 0 ) {} - virtual ~XMLAttribute() {} - - XMLAttribute( const XMLAttribute& ); // not supported - void operator=( const XMLAttribute& ); // not supported - void SetName( const char* name ); - - char* ParseDeep( char* p, bool processEntities, int* curLineNumPtr ); - - mutable StrPair _name; - mutable StrPair _value; - int _parseLineNum; - XMLAttribute* _next; - MemPool* _memPool; -}; - - -/** The element is a container class. It has a value, the element name, - and can contain other elements, text, comments, and unknowns. - Elements also contain an arbitrary number of attributes. -*/ -class TINYXML2_LIB XMLElement : public XMLNode -{ - friend class XMLDocument; -public: - /// Get the name of an element (which is the Value() of the node.) - const char* Name() const { - return Value(); - } - /// Set the name of the element. - void SetName( const char* str, bool staticMem=false ) { - SetValue( str, staticMem ); - } - - virtual XMLElement* ToElement() { - return this; - } - virtual const XMLElement* ToElement() const { - return this; - } - virtual bool Accept( XMLVisitor* visitor ) const; - - /** Given an attribute name, Attribute() returns the value - for the attribute of that name, or null if none - exists. For example: - - @verbatim - const char* value = ele->Attribute( "foo" ); - @endverbatim - - The 'value' parameter is normally null. However, if specified, - the attribute will only be returned if the 'name' and 'value' - match. This allow you to write code: - - @verbatim - if ( ele->Attribute( "foo", "bar" ) ) callFooIsBar(); - @endverbatim - - rather than: - @verbatim - if ( ele->Attribute( "foo" ) ) { - if ( strcmp( ele->Attribute( "foo" ), "bar" ) == 0 ) callFooIsBar(); - } - @endverbatim - */ - const char* Attribute( const char* name, const char* value=0 ) const; - - /** Given an attribute name, IntAttribute() returns the value - of the attribute interpreted as an integer. The default - value will be returned if the attribute isn't present, - or if there is an error. (For a method with error - checking, see QueryIntAttribute()). - */ - int IntAttribute(const char* name, int defaultValue = 0) const; - /// See IntAttribute() - unsigned UnsignedAttribute(const char* name, unsigned defaultValue = 0) const; - /// See IntAttribute() - int64_t Int64Attribute(const char* name, int64_t defaultValue = 0) const; - /// See IntAttribute() - uint64_t Unsigned64Attribute(const char* name, uint64_t defaultValue = 0) const; - /// See IntAttribute() - bool BoolAttribute(const char* name, bool defaultValue = false) const; - /// See IntAttribute() - double DoubleAttribute(const char* name, double defaultValue = 0) const; - /// See IntAttribute() - float FloatAttribute(const char* name, float defaultValue = 0) const; - - /** Given an attribute name, QueryIntAttribute() returns - XML_SUCCESS, XML_WRONG_ATTRIBUTE_TYPE if the conversion - can't be performed, or XML_NO_ATTRIBUTE if the attribute - doesn't exist. If successful, the result of the conversion - will be written to 'value'. If not successful, nothing will - be written to 'value'. This allows you to provide default - value: - - @verbatim - int value = 10; - QueryIntAttribute( "foo", &value ); // if "foo" isn't found, value will still be 10 - @endverbatim - */ - XMLError QueryIntAttribute( const char* name, int* value ) const { - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return XML_NO_ATTRIBUTE; - } - return a->QueryIntValue( value ); - } - - /// See QueryIntAttribute() - XMLError QueryUnsignedAttribute( const char* name, unsigned int* value ) const { - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return XML_NO_ATTRIBUTE; - } - return a->QueryUnsignedValue( value ); - } - - /// See QueryIntAttribute() - XMLError QueryInt64Attribute(const char* name, int64_t* value) const { - const XMLAttribute* a = FindAttribute(name); - if (!a) { - return XML_NO_ATTRIBUTE; - } - return a->QueryInt64Value(value); - } - - /// See QueryIntAttribute() - XMLError QueryUnsigned64Attribute(const char* name, uint64_t* value) const { - const XMLAttribute* a = FindAttribute(name); - if(!a) { - return XML_NO_ATTRIBUTE; - } - return a->QueryUnsigned64Value(value); - } - - /// See QueryIntAttribute() - XMLError QueryBoolAttribute( const char* name, bool* value ) const { - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return XML_NO_ATTRIBUTE; - } - return a->QueryBoolValue( value ); - } - /// See QueryIntAttribute() - XMLError QueryDoubleAttribute( const char* name, double* value ) const { - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return XML_NO_ATTRIBUTE; - } - return a->QueryDoubleValue( value ); - } - /// See QueryIntAttribute() - XMLError QueryFloatAttribute( const char* name, float* value ) const { - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return XML_NO_ATTRIBUTE; - } - return a->QueryFloatValue( value ); - } - - /// See QueryIntAttribute() - XMLError QueryStringAttribute(const char* name, const char** value) const { - const XMLAttribute* a = FindAttribute(name); - if (!a) { - return XML_NO_ATTRIBUTE; - } - *value = a->Value(); - return XML_SUCCESS; - } - - - - /** Given an attribute name, QueryAttribute() returns - XML_SUCCESS, XML_WRONG_ATTRIBUTE_TYPE if the conversion - can't be performed, or XML_NO_ATTRIBUTE if the attribute - doesn't exist. It is overloaded for the primitive types, - and is a generally more convenient replacement of - QueryIntAttribute() and related functions. - - If successful, the result of the conversion - will be written to 'value'. If not successful, nothing will - be written to 'value'. This allows you to provide default - value: - - @verbatim - int value = 10; - QueryAttribute( "foo", &value ); // if "foo" isn't found, value will still be 10 - @endverbatim - */ - XMLError QueryAttribute( const char* name, int* value ) const { - return QueryIntAttribute( name, value ); - } - - XMLError QueryAttribute( const char* name, unsigned int* value ) const { - return QueryUnsignedAttribute( name, value ); - } - - XMLError QueryAttribute(const char* name, int64_t* value) const { - return QueryInt64Attribute(name, value); - } - - XMLError QueryAttribute(const char* name, uint64_t* value) const { - return QueryUnsigned64Attribute(name, value); - } - - XMLError QueryAttribute( const char* name, bool* value ) const { - return QueryBoolAttribute( name, value ); - } - - XMLError QueryAttribute( const char* name, double* value ) const { - return QueryDoubleAttribute( name, value ); - } - - XMLError QueryAttribute( const char* name, float* value ) const { - return QueryFloatAttribute( name, value ); - } - - XMLError QueryAttribute(const char* name, const char** value) const { - return QueryStringAttribute(name, value); - } - - /// Sets the named attribute to value. - void SetAttribute( const char* name, const char* value ) { - XMLAttribute* a = FindOrCreateAttribute( name ); - a->SetAttribute( value ); - } - /// Sets the named attribute to value. - void SetAttribute( const char* name, int value ) { - XMLAttribute* a = FindOrCreateAttribute( name ); - a->SetAttribute( value ); - } - /// Sets the named attribute to value. - void SetAttribute( const char* name, unsigned value ) { - XMLAttribute* a = FindOrCreateAttribute( name ); - a->SetAttribute( value ); - } - - /// Sets the named attribute to value. - void SetAttribute(const char* name, int64_t value) { - XMLAttribute* a = FindOrCreateAttribute(name); - a->SetAttribute(value); - } - - /// Sets the named attribute to value. - void SetAttribute(const char* name, uint64_t value) { - XMLAttribute* a = FindOrCreateAttribute(name); - a->SetAttribute(value); - } - - /// Sets the named attribute to value. - void SetAttribute( const char* name, bool value ) { - XMLAttribute* a = FindOrCreateAttribute( name ); - a->SetAttribute( value ); - } - /// Sets the named attribute to value. - void SetAttribute( const char* name, double value ) { - XMLAttribute* a = FindOrCreateAttribute( name ); - a->SetAttribute( value ); - } - /// Sets the named attribute to value. - void SetAttribute( const char* name, float value ) { - XMLAttribute* a = FindOrCreateAttribute( name ); - a->SetAttribute( value ); - } - - /** - Delete an attribute. - */ - void DeleteAttribute( const char* name ); - - /// Return the first attribute in the list. - const XMLAttribute* FirstAttribute() const { - return _rootAttribute; - } - /// Query a specific attribute in the list. - const XMLAttribute* FindAttribute( const char* name ) const; - - /** Convenience function for easy access to the text inside an element. Although easy - and concise, GetText() is limited compared to getting the XMLText child - and accessing it directly. - - If the first child of 'this' is a XMLText, the GetText() - returns the character string of the Text node, else null is returned. - - This is a convenient method for getting the text of simple contained text: - @verbatim - This is text - const char* str = fooElement->GetText(); - @endverbatim - - 'str' will be a pointer to "This is text". - - Note that this function can be misleading. If the element foo was created from - this XML: - @verbatim - This is text - @endverbatim - - then the value of str would be null. The first child node isn't a text node, it is - another element. From this XML: - @verbatim - This is text - @endverbatim - GetText() will return "This is ". - */ - const char* GetText() const; - - /** Convenience function for easy access to the text inside an element. Although easy - and concise, SetText() is limited compared to creating an XMLText child - and mutating it directly. - - If the first child of 'this' is a XMLText, SetText() sets its value to - the given string, otherwise it will create a first child that is an XMLText. - - This is a convenient method for setting the text of simple contained text: - @verbatim - This is text - fooElement->SetText( "Hullaballoo!" ); - Hullaballoo! - @endverbatim - - Note that this function can be misleading. If the element foo was created from - this XML: - @verbatim - This is text - @endverbatim - - then it will not change "This is text", but rather prefix it with a text element: - @verbatim - Hullaballoo!This is text - @endverbatim - - For this XML: - @verbatim - - @endverbatim - SetText() will generate - @verbatim - Hullaballoo! - @endverbatim - */ - void SetText( const char* inText ); - /// Convenience method for setting text inside an element. See SetText() for important limitations. - void SetText( int value ); - /// Convenience method for setting text inside an element. See SetText() for important limitations. - void SetText( unsigned value ); - /// Convenience method for setting text inside an element. See SetText() for important limitations. - void SetText(int64_t value); - /// Convenience method for setting text inside an element. See SetText() for important limitations. - void SetText(uint64_t value); - /// Convenience method for setting text inside an element. See SetText() for important limitations. - void SetText( bool value ); - /// Convenience method for setting text inside an element. See SetText() for important limitations. - void SetText( double value ); - /// Convenience method for setting text inside an element. See SetText() for important limitations. - void SetText( float value ); - - /** - Convenience method to query the value of a child text node. This is probably best - shown by example. Given you have a document is this form: - @verbatim - - 1 - 1.4 - - @endverbatim - - The QueryIntText() and similar functions provide a safe and easier way to get to the - "value" of x and y. - - @verbatim - int x = 0; - float y = 0; // types of x and y are contrived for example - const XMLElement* xElement = pointElement->FirstChildElement( "x" ); - const XMLElement* yElement = pointElement->FirstChildElement( "y" ); - xElement->QueryIntText( &x ); - yElement->QueryFloatText( &y ); - @endverbatim - - @returns XML_SUCCESS (0) on success, XML_CAN_NOT_CONVERT_TEXT if the text cannot be converted - to the requested type, and XML_NO_TEXT_NODE if there is no child text to query. - - */ - XMLError QueryIntText( int* ival ) const; - /// See QueryIntText() - XMLError QueryUnsignedText( unsigned* uval ) const; - /// See QueryIntText() - XMLError QueryInt64Text(int64_t* uval) const; - /// See QueryIntText() - XMLError QueryUnsigned64Text(uint64_t* uval) const; - /// See QueryIntText() - XMLError QueryBoolText( bool* bval ) const; - /// See QueryIntText() - XMLError QueryDoubleText( double* dval ) const; - /// See QueryIntText() - XMLError QueryFloatText( float* fval ) const; - - int IntText(int defaultValue = 0) const; - - /// See QueryIntText() - unsigned UnsignedText(unsigned defaultValue = 0) const; - /// See QueryIntText() - int64_t Int64Text(int64_t defaultValue = 0) const; - /// See QueryIntText() - uint64_t Unsigned64Text(uint64_t defaultValue = 0) const; - /// See QueryIntText() - bool BoolText(bool defaultValue = false) const; - /// See QueryIntText() - double DoubleText(double defaultValue = 0) const; - /// See QueryIntText() - float FloatText(float defaultValue = 0) const; - - /** - Convenience method to create a new XMLElement and add it as last (right) - child of this node. Returns the created and inserted element. - */ - XMLElement* InsertNewChildElement(const char* name); - /// See InsertNewChildElement() - XMLComment* InsertNewComment(const char* comment); - /// See InsertNewChildElement() - XMLText* InsertNewText(const char* text); - /// See InsertNewChildElement() - XMLDeclaration* InsertNewDeclaration(const char* text); - /// See InsertNewChildElement() - XMLUnknown* InsertNewUnknown(const char* text); - - - // internal: - enum ElementClosingType { - OPEN, // - CLOSED, // - CLOSING // - }; - ElementClosingType ClosingType() const { - return _closingType; - } - virtual XMLNode* ShallowClone( XMLDocument* document ) const; - virtual bool ShallowEqual( const XMLNode* compare ) const; - -protected: - char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ); - -private: - XMLElement( XMLDocument* doc ); - virtual ~XMLElement(); - XMLElement( const XMLElement& ); // not supported - void operator=( const XMLElement& ); // not supported - - XMLAttribute* FindOrCreateAttribute( const char* name ); - char* ParseAttributes( char* p, int* curLineNumPtr ); - static void DeleteAttribute( XMLAttribute* attribute ); - XMLAttribute* CreateAttribute(); - - enum { BUF_SIZE = 200 }; - ElementClosingType _closingType; - // The attribute list is ordered; there is no 'lastAttribute' - // because the list needs to be scanned for dupes before adding - // a new attribute. - XMLAttribute* _rootAttribute; -}; - - -enum Whitespace { - PRESERVE_WHITESPACE, - COLLAPSE_WHITESPACE -}; - - -/** A Document binds together all the functionality. - It can be saved, loaded, and printed to the screen. - All Nodes are connected and allocated to a Document. - If the Document is deleted, all its Nodes are also deleted. -*/ -class TINYXML2_LIB XMLDocument : public XMLNode -{ - friend class XMLElement; - // Gives access to SetError and Push/PopDepth, but over-access for everything else. - // Wishing C++ had "internal" scope. - friend class XMLNode; - friend class XMLText; - friend class XMLComment; - friend class XMLDeclaration; - friend class XMLUnknown; -public: - /// constructor - XMLDocument( bool processEntities = true, Whitespace whitespaceMode = PRESERVE_WHITESPACE ); - ~XMLDocument(); - - virtual XMLDocument* ToDocument() { - TIXMLASSERT( this == _document ); - return this; - } - virtual const XMLDocument* ToDocument() const { - TIXMLASSERT( this == _document ); - return this; - } - - /** - Parse an XML file from a character string. - Returns XML_SUCCESS (0) on success, or - an errorID. - - You may optionally pass in the 'nBytes', which is - the number of bytes which will be parsed. If not - specified, TinyXML-2 will assume 'xml' points to a - null terminated string. - */ - XMLError Parse( const char* xml, size_t nBytes=static_cast(-1) ); - - /** - Load an XML file from disk. - Returns XML_SUCCESS (0) on success, or - an errorID. - */ - XMLError LoadFile( const char* filename ); - - /** - Load an XML file from disk. You are responsible - for providing and closing the FILE*. - - NOTE: The file should be opened as binary ("rb") - not text in order for TinyXML-2 to correctly - do newline normalization. - - Returns XML_SUCCESS (0) on success, or - an errorID. - */ - XMLError LoadFile( FILE* ); - - /** - Save the XML file to disk. - Returns XML_SUCCESS (0) on success, or - an errorID. - */ - XMLError SaveFile( const char* filename, bool compact = false ); - - /** - Save the XML file to disk. You are responsible - for providing and closing the FILE*. - - Returns XML_SUCCESS (0) on success, or - an errorID. - */ - XMLError SaveFile( FILE* fp, bool compact = false ); - - bool ProcessEntities() const { - return _processEntities; - } - Whitespace WhitespaceMode() const { - return _whitespaceMode; - } - - /** - Returns true if this document has a leading Byte Order Mark of UTF8. - */ - bool HasBOM() const { - return _writeBOM; - } - /** Sets whether to write the BOM when writing the file. - */ - void SetBOM( bool useBOM ) { - _writeBOM = useBOM; - } - - /** Return the root element of DOM. Equivalent to FirstChildElement(). - To get the first node, use FirstChild(). - */ - XMLElement* RootElement() { - return FirstChildElement(); - } - const XMLElement* RootElement() const { - return FirstChildElement(); - } - - /** Print the Document. If the Printer is not provided, it will - print to stdout. If you provide Printer, this can print to a file: - @verbatim - XMLPrinter printer( fp ); - doc.Print( &printer ); - @endverbatim - - Or you can use a printer to print to memory: - @verbatim - XMLPrinter printer; - doc.Print( &printer ); - // printer.CStr() has a const char* to the XML - @endverbatim - */ - void Print( XMLPrinter* streamer=0 ) const; - virtual bool Accept( XMLVisitor* visitor ) const; - - /** - Create a new Element associated with - this Document. The memory for the Element - is managed by the Document. - */ - XMLElement* NewElement( const char* name ); - /** - Create a new Comment associated with - this Document. The memory for the Comment - is managed by the Document. - */ - XMLComment* NewComment( const char* comment ); - /** - Create a new Text associated with - this Document. The memory for the Text - is managed by the Document. - */ - XMLText* NewText( const char* text ); - /** - Create a new Declaration associated with - this Document. The memory for the object - is managed by the Document. - - If the 'text' param is null, the standard - declaration is used.: - @verbatim - - @endverbatim - */ - XMLDeclaration* NewDeclaration( const char* text=0 ); - /** - Create a new Unknown associated with - this Document. The memory for the object - is managed by the Document. - */ - XMLUnknown* NewUnknown( const char* text ); - - /** - Delete a node associated with this document. - It will be unlinked from the DOM. - */ - void DeleteNode( XMLNode* node ); - - /// Clears the error flags. - void ClearError(); - - /// Return true if there was an error parsing the document. - bool Error() const { - return _errorID != XML_SUCCESS; - } - /// Return the errorID. - XMLError ErrorID() const { - return _errorID; - } - const char* ErrorName() const; - static const char* ErrorIDToName(XMLError errorID); - - /** Returns a "long form" error description. A hopefully helpful - diagnostic with location, line number, and/or additional info. - */ - const char* ErrorStr() const; - - /// A (trivial) utility function that prints the ErrorStr() to stdout. - void PrintError() const; - - /// Return the line where the error occurred, or zero if unknown. - int ErrorLineNum() const - { - return _errorLineNum; - } - - /// Clear the document, resetting it to the initial state. - void Clear(); - - /** - Copies this document to a target document. - The target will be completely cleared before the copy. - If you want to copy a sub-tree, see XMLNode::DeepClone(). - - NOTE: that the 'target' must be non-null. - */ - void DeepCopy(XMLDocument* target) const; - - // internal - char* Identify( char* p, XMLNode** node ); - - // internal - void MarkInUse(const XMLNode* const); - - virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const { - return 0; - } - virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const { - return false; - } - -private: - XMLDocument( const XMLDocument& ); // not supported - void operator=( const XMLDocument& ); // not supported - - bool _writeBOM; - bool _processEntities; - XMLError _errorID; - Whitespace _whitespaceMode; - mutable StrPair _errorStr; - int _errorLineNum; - char* _charBuffer; - int _parseCurLineNum; - int _parsingDepth; - // Memory tracking does add some overhead. - // However, the code assumes that you don't - // have a bunch of unlinked nodes around. - // Therefore it takes less memory to track - // in the document vs. a linked list in the XMLNode, - // and the performance is the same. - DynArray _unlinked; - - MemPoolT< sizeof(XMLElement) > _elementPool; - MemPoolT< sizeof(XMLAttribute) > _attributePool; - MemPoolT< sizeof(XMLText) > _textPool; - MemPoolT< sizeof(XMLComment) > _commentPool; - - static const char* _errorNames[XML_ERROR_COUNT]; - - void Parse(); - - void SetError( XMLError error, int lineNum, const char* format, ... ); - - // Something of an obvious security hole, once it was discovered. - // Either an ill-formed XML or an excessively deep one can overflow - // the stack. Track stack depth, and error out if needed. - class DepthTracker { - public: - explicit DepthTracker(XMLDocument * document) { - this->_document = document; - document->PushDepth(); - } - ~DepthTracker() { - _document->PopDepth(); - } - private: - XMLDocument * _document; - }; - void PushDepth(); - void PopDepth(); - - template - NodeType* CreateUnlinkedNode( MemPoolT& pool ); -}; - -template -inline NodeType* XMLDocument::CreateUnlinkedNode( MemPoolT& pool ) -{ - TIXMLASSERT( sizeof( NodeType ) == PoolElementSize ); - TIXMLASSERT( sizeof( NodeType ) == pool.ItemSize() ); - NodeType* returnNode = new (pool.Alloc()) NodeType( this ); - TIXMLASSERT( returnNode ); - returnNode->_memPool = &pool; - - _unlinked.Push(returnNode); - return returnNode; -} - -/** - A XMLHandle is a class that wraps a node pointer with null checks; this is - an incredibly useful thing. Note that XMLHandle is not part of the TinyXML-2 - DOM structure. It is a separate utility class. - - Take an example: - @verbatim - - - - - - - @endverbatim - - Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very - easy to write a *lot* of code that looks like: - - @verbatim - XMLElement* root = document.FirstChildElement( "Document" ); - if ( root ) - { - XMLElement* element = root->FirstChildElement( "Element" ); - if ( element ) - { - XMLElement* child = element->FirstChildElement( "Child" ); - if ( child ) - { - XMLElement* child2 = child->NextSiblingElement( "Child" ); - if ( child2 ) - { - // Finally do something useful. - @endverbatim - - And that doesn't even cover "else" cases. XMLHandle addresses the verbosity - of such code. A XMLHandle checks for null pointers so it is perfectly safe - and correct to use: - - @verbatim - XMLHandle docHandle( &document ); - XMLElement* child2 = docHandle.FirstChildElement( "Document" ).FirstChildElement( "Element" ).FirstChildElement().NextSiblingElement(); - if ( child2 ) - { - // do something useful - @endverbatim - - Which is MUCH more concise and useful. - - It is also safe to copy handles - internally they are nothing more than node pointers. - @verbatim - XMLHandle handleCopy = handle; - @endverbatim - - See also XMLConstHandle, which is the same as XMLHandle, but operates on const objects. -*/ -class TINYXML2_LIB XMLHandle -{ -public: - /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. - explicit XMLHandle( XMLNode* node ) : _node( node ) { - } - /// Create a handle from a node. - explicit XMLHandle( XMLNode& node ) : _node( &node ) { - } - /// Copy constructor - XMLHandle( const XMLHandle& ref ) : _node( ref._node ) { - } - /// Assignment - XMLHandle& operator=( const XMLHandle& ref ) { - _node = ref._node; - return *this; - } - - /// Get the first child of this handle. - XMLHandle FirstChild() { - return XMLHandle( _node ? _node->FirstChild() : 0 ); - } - /// Get the first child element of this handle. - XMLHandle FirstChildElement( const char* name = 0 ) { - return XMLHandle( _node ? _node->FirstChildElement( name ) : 0 ); - } - /// Get the last child of this handle. - XMLHandle LastChild() { - return XMLHandle( _node ? _node->LastChild() : 0 ); - } - /// Get the last child element of this handle. - XMLHandle LastChildElement( const char* name = 0 ) { - return XMLHandle( _node ? _node->LastChildElement( name ) : 0 ); - } - /// Get the previous sibling of this handle. - XMLHandle PreviousSibling() { - return XMLHandle( _node ? _node->PreviousSibling() : 0 ); - } - /// Get the previous sibling element of this handle. - XMLHandle PreviousSiblingElement( const char* name = 0 ) { - return XMLHandle( _node ? _node->PreviousSiblingElement( name ) : 0 ); - } - /// Get the next sibling of this handle. - XMLHandle NextSibling() { - return XMLHandle( _node ? _node->NextSibling() : 0 ); - } - /// Get the next sibling element of this handle. - XMLHandle NextSiblingElement( const char* name = 0 ) { - return XMLHandle( _node ? _node->NextSiblingElement( name ) : 0 ); - } - - /// Safe cast to XMLNode. This can return null. - XMLNode* ToNode() { - return _node; - } - /// Safe cast to XMLElement. This can return null. - XMLElement* ToElement() { - return ( _node ? _node->ToElement() : 0 ); - } - /// Safe cast to XMLText. This can return null. - XMLText* ToText() { - return ( _node ? _node->ToText() : 0 ); - } - /// Safe cast to XMLUnknown. This can return null. - XMLUnknown* ToUnknown() { - return ( _node ? _node->ToUnknown() : 0 ); - } - /// Safe cast to XMLDeclaration. This can return null. - XMLDeclaration* ToDeclaration() { - return ( _node ? _node->ToDeclaration() : 0 ); - } - -private: - XMLNode* _node; -}; - - -/** - A variant of the XMLHandle class for working with const XMLNodes and Documents. It is the - same in all regards, except for the 'const' qualifiers. See XMLHandle for API. -*/ -class TINYXML2_LIB XMLConstHandle -{ -public: - explicit XMLConstHandle( const XMLNode* node ) : _node( node ) { - } - explicit XMLConstHandle( const XMLNode& node ) : _node( &node ) { - } - XMLConstHandle( const XMLConstHandle& ref ) : _node( ref._node ) { - } - - XMLConstHandle& operator=( const XMLConstHandle& ref ) { - _node = ref._node; - return *this; - } - - const XMLConstHandle FirstChild() const { - return XMLConstHandle( _node ? _node->FirstChild() : 0 ); - } - const XMLConstHandle FirstChildElement( const char* name = 0 ) const { - return XMLConstHandle( _node ? _node->FirstChildElement( name ) : 0 ); - } - const XMLConstHandle LastChild() const { - return XMLConstHandle( _node ? _node->LastChild() : 0 ); - } - const XMLConstHandle LastChildElement( const char* name = 0 ) const { - return XMLConstHandle( _node ? _node->LastChildElement( name ) : 0 ); - } - const XMLConstHandle PreviousSibling() const { - return XMLConstHandle( _node ? _node->PreviousSibling() : 0 ); - } - const XMLConstHandle PreviousSiblingElement( const char* name = 0 ) const { - return XMLConstHandle( _node ? _node->PreviousSiblingElement( name ) : 0 ); - } - const XMLConstHandle NextSibling() const { - return XMLConstHandle( _node ? _node->NextSibling() : 0 ); - } - const XMLConstHandle NextSiblingElement( const char* name = 0 ) const { - return XMLConstHandle( _node ? _node->NextSiblingElement( name ) : 0 ); - } - - - const XMLNode* ToNode() const { - return _node; - } - const XMLElement* ToElement() const { - return ( _node ? _node->ToElement() : 0 ); - } - const XMLText* ToText() const { - return ( _node ? _node->ToText() : 0 ); - } - const XMLUnknown* ToUnknown() const { - return ( _node ? _node->ToUnknown() : 0 ); - } - const XMLDeclaration* ToDeclaration() const { - return ( _node ? _node->ToDeclaration() : 0 ); - } - -private: - const XMLNode* _node; -}; - - -/** - Printing functionality. The XMLPrinter gives you more - options than the XMLDocument::Print() method. - - It can: - -# Print to memory. - -# Print to a file you provide. - -# Print XML without a XMLDocument. - - Print to Memory - - @verbatim - XMLPrinter printer; - doc.Print( &printer ); - SomeFunction( printer.CStr() ); - @endverbatim - - Print to a File - - You provide the file pointer. - @verbatim - XMLPrinter printer( fp ); - doc.Print( &printer ); - @endverbatim - - Print without a XMLDocument - - When loading, an XML parser is very useful. However, sometimes - when saving, it just gets in the way. The code is often set up - for streaming, and constructing the DOM is just overhead. - - The Printer supports the streaming case. The following code - prints out a trivially simple XML file without ever creating - an XML document. - - @verbatim - XMLPrinter printer( fp ); - printer.OpenElement( "foo" ); - printer.PushAttribute( "foo", "bar" ); - printer.CloseElement(); - @endverbatim -*/ -class TINYXML2_LIB XMLPrinter : public XMLVisitor -{ -public: - /** Construct the printer. If the FILE* is specified, - this will print to the FILE. Else it will print - to memory, and the result is available in CStr(). - If 'compact' is set to true, then output is created - with only required whitespace and newlines. - */ - XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 ); - virtual ~XMLPrinter() {} - - /** If streaming, write the BOM and declaration. */ - void PushHeader( bool writeBOM, bool writeDeclaration ); - /** If streaming, start writing an element. - The element must be closed with CloseElement() - */ - void OpenElement( const char* name, bool compactMode=false ); - /// If streaming, add an attribute to an open element. - void PushAttribute( const char* name, const char* value ); - void PushAttribute( const char* name, int value ); - void PushAttribute( const char* name, unsigned value ); - void PushAttribute( const char* name, int64_t value ); - void PushAttribute( const char* name, uint64_t value ); - void PushAttribute( const char* name, bool value ); - void PushAttribute( const char* name, double value ); - /// If streaming, close the Element. - virtual void CloseElement( bool compactMode=false ); - - /// Add a text node. - void PushText( const char* text, bool cdata=false ); - /// Add a text node from an integer. - void PushText( int value ); - /// Add a text node from an unsigned. - void PushText( unsigned value ); - /// Add a text node from a signed 64bit integer. - void PushText( int64_t value ); - /// Add a text node from an unsigned 64bit integer. - void PushText( uint64_t value ); - /// Add a text node from a bool. - void PushText( bool value ); - /// Add a text node from a float. - void PushText( float value ); - /// Add a text node from a double. - void PushText( double value ); - - /// Add a comment - void PushComment( const char* comment ); - - void PushDeclaration( const char* value ); - void PushUnknown( const char* value ); - - virtual bool VisitEnter( const XMLDocument& /*doc*/ ); - virtual bool VisitExit( const XMLDocument& /*doc*/ ) { - return true; - } - - virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute ); - virtual bool VisitExit( const XMLElement& element ); - - virtual bool Visit( const XMLText& text ); - virtual bool Visit( const XMLComment& comment ); - virtual bool Visit( const XMLDeclaration& declaration ); - virtual bool Visit( const XMLUnknown& unknown ); - - /** - If in print to memory mode, return a pointer to - the XML file in memory. - */ - const char* CStr() const { - return _buffer.Mem(); - } - /** - If in print to memory mode, return the size - of the XML file in memory. (Note the size returned - includes the terminating null.) - */ - int CStrSize() const { - return _buffer.Size(); - } - /** - If in print to memory mode, reset the buffer to the - beginning. - */ - void ClearBuffer( bool resetToFirstElement = true ) { - _buffer.Clear(); - _buffer.Push(0); - _firstElement = resetToFirstElement; - } - -protected: - virtual bool CompactMode( const XMLElement& ) { return _compactMode; } - - /** Prints out the space before an element. You may override to change - the space and tabs used. A PrintSpace() override should call Print(). - */ - virtual void PrintSpace( int depth ); - virtual void Print( const char* format, ... ); - virtual void Write( const char* data, size_t size ); - virtual void Putc( char ch ); - - inline void Write(const char* data) { Write(data, strlen(data)); } - - void SealElementIfJustOpened(); - bool _elementJustOpened; - DynArray< const char*, 10 > _stack; - -private: - /** - Prepares to write a new node. This includes sealing an element that was - just opened, and writing any whitespace necessary if not in compact mode. - */ - void PrepareForNewNode( bool compactMode ); - void PrintString( const char*, bool restrictedEntitySet ); // prints out, after detecting entities. - - bool _firstElement; - FILE* _fp; - int _depth; - int _textDepth; - bool _processEntities; - bool _compactMode; - - enum { - ENTITY_RANGE = 64, - BUF_SIZE = 200 - }; - bool _entityFlag[ENTITY_RANGE]; - bool _restrictedEntityFlag[ENTITY_RANGE]; - - DynArray< char, 20 > _buffer; - - // Prohibit cloning, intentionally not implemented - XMLPrinter( const XMLPrinter& ); - XMLPrinter& operator=( const XMLPrinter& ); -}; - - -} // tinyxml2 - -#if defined(_MSC_VER) -# pragma warning(pop) -#endif - -#endif // TINYXML2_INCLUDED diff --git a/binding.gyp b/binding.gyp index 5cae6115..9775594f 100644 --- a/binding.gyp +++ b/binding.gyp @@ -6,8 +6,6 @@ "cflags_cc!": [ "-fno-exceptions" ], "sources": [ "addon/api.cpp", - "addon/tinyxml2/tinyxml2.cpp", - "addon/TinyEXIF/TinyEXIF.cpp" ], "include_dirs": [ "=6.9.0'} + dev: true /@babel/helper-validator-identifier@7.22.20: resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} engines: {node: '>=6.9.0'} + dev: true /@babel/helper-validator-option@7.22.15: resolution: {integrity: sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==} @@ -869,6 +871,7 @@ packages: hasBin: true dependencies: '@babel/types': 7.23.0 + dev: true /@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.23.2): resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} @@ -1306,6 +1309,7 @@ packages: '@babel/helper-string-parser': 7.22.5 '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 + dev: true /@bcoe/v8-coverage@0.2.3: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} @@ -1411,14 +1415,14 @@ packages: '@commitlint/types': 17.8.1 '@types/node': 20.5.1 chalk: 4.1.2 - cosmiconfig: 8.3.6(typescript@5.3.2) - cosmiconfig-typescript-loader: 4.4.0(@types/node@20.5.1)(cosmiconfig@8.3.6)(ts-node@10.9.1)(typescript@5.3.2) + cosmiconfig: 8.3.6(typescript@5.3.3) + cosmiconfig-typescript-loader: 4.4.0(@types/node@20.5.1)(cosmiconfig@8.3.6)(ts-node@10.9.2)(typescript@5.3.3) lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 lodash.uniq: 4.5.0 resolve-from: 5.0.0 - ts-node: 10.9.1(@swc/core@1.3.94)(@types/node@20.5.1)(typescript@5.3.2) - typescript: 5.3.2 + ts-node: 10.9.2(@swc/core@1.3.94)(@types/node@20.5.1)(typescript@5.3.3) + typescript: 5.3.3 transitivePeerDependencies: - '@swc/core' - '@swc/wasm' @@ -1444,7 +1448,7 @@ packages: dependencies: '@commitlint/top-level': 17.8.1 '@commitlint/types': 17.8.1 - fs-extra: 11.1.1 + fs-extra: 11.2.0 git-raw-commits: 2.0.11 minimist: 1.2.8 dev: true @@ -1602,6 +1606,14 @@ packages: - supports-color dev: false + /@emnapi/runtime@0.44.0: + resolution: {integrity: sha512-ZX/etZEZw8DR7zAB1eVQT40lNo0jeqpb6dCgOvctB6FIQ5PoXfMuNY8+ayQfu8tNQbAB8gQWSSJupR8NxeiZXw==} + requiresBuild: true + dependencies: + tslib: 2.6.2 + dev: false + optional: true + /@eslint-community/eslint-utils@4.4.0(eslint@8.52.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1784,6 +1796,10 @@ packages: - supports-color dev: false + /@firebase/app-check-interop-types@0.3.0: + resolution: {integrity: sha512-xAxHPZPIgFXnI+vb4sbBjZcde7ZluzPPaSK7Lx3/nmuVk4TjZvnL8ONnkd4ERQKL8WePQySU+pRcWkh8rDf5Sg==} + dev: false + /@firebase/app-types@0.9.0: resolution: {integrity: sha512-AeweANOIo0Mb8GiYm3xhTEBVCmPwTYAu9Hcd2qSkLuga/6+j9b1Jskl5bpiSQWy9eJ/j5pavxj6eYogmnuzm+Q==} dev: false @@ -1799,27 +1815,28 @@ packages: tslib: 2.6.2 dev: false - /@firebase/database-compat@0.3.4: - resolution: {integrity: sha512-kuAW+l+sLMUKBThnvxvUZ+Q1ZrF/vFJ58iUY9kAcbX48U03nVzIF6Tmkf0p3WVQwMqiXguSgtOPIB6ZCeF+5Gg==} + /@firebase/database-compat@1.0.2: + resolution: {integrity: sha512-09ryJnXDvuycsxn8aXBzLhBTuCos3HEnCOBWY6hosxfYlNCGnLvG8YMlbSAt5eNhf7/00B095AEfDsdrrLjxqA==} dependencies: '@firebase/component': 0.6.4 - '@firebase/database': 0.14.4 - '@firebase/database-types': 0.10.4 + '@firebase/database': 1.0.2 + '@firebase/database-types': 1.0.0 '@firebase/logger': 0.4.0 '@firebase/util': 1.9.3 tslib: 2.6.2 dev: false - /@firebase/database-types@0.10.4: - resolution: {integrity: sha512-dPySn0vJ/89ZeBac70T+2tWWPiJXWbmRygYv0smT5TfE3hDrQ09eKMF3Y+vMlTdrMWq7mUdYW5REWPSGH4kAZQ==} + /@firebase/database-types@1.0.0: + resolution: {integrity: sha512-SjnXStoE0Q56HcFgNQ+9SsmJc0c8TqGARdI/T44KXy+Ets3r6x/ivhQozT66bMnCEjJRywYoxNurRTMlZF8VNg==} dependencies: '@firebase/app-types': 0.9.0 '@firebase/util': 1.9.3 dev: false - /@firebase/database@0.14.4: - resolution: {integrity: sha512-+Ea/IKGwh42jwdjCyzTmeZeLM3oy1h0mFPsTy6OqCWzcu/KFqRAr5Tt1HRCOBlNOdbh84JPZC47WLU18n2VbxQ==} + /@firebase/database@1.0.2: + resolution: {integrity: sha512-8X6NBJgUQzDz0xQVaCISoOLINKat594N2eBbMR3Mu/MH/ei4WM+aAMlsNzngF22eljXu1SILP5G3evkyvsG3Ng==} dependencies: + '@firebase/app-check-interop-types': 0.3.0 '@firebase/auth-interop-types': 0.2.1 '@firebase/component': 0.6.4 '@firebase/logger': 0.4.0 @@ -1840,14 +1857,14 @@ packages: tslib: 2.6.2 dev: false - /@google-cloud/firestore@6.8.0: - resolution: {integrity: sha512-JRpk06SmZXLGz0pNx1x7yU3YhkUXheKgH5hbDZ4kMsdhtfV5qPLJLRI4wv69K0cZorIk+zTMOwptue7hizo0eA==} - engines: {node: '>=12.0.0'} + /@google-cloud/firestore@7.1.0: + resolution: {integrity: sha512-kkTC0Sb9r2lONuFF8Tr2wFfBfk0DT1/EKcTKOhsuoXUVClv3jCqGYVPtHgQsHFjdOsubS+tx9G5D5WG+obB2DA==} + engines: {node: '>=14.0.0'} requiresBuild: true dependencies: fast-deep-equal: 3.1.3 functional-red-black-tree: 1.0.1 - google-gax: 3.6.1 + google-gax: 4.0.5 protobufjs: 7.2.5 transitivePeerDependencies: - encoding @@ -1855,9 +1872,9 @@ packages: dev: false optional: true - /@google-cloud/paginator@3.0.7: - resolution: {integrity: sha512-jJNutk0arIQhmpUUQJPJErsojqo834KcyB6X7a1mxuic8i1tKXxde8E69IZxNZawRIlZdIK2QY4WALvlK5MzYQ==} - engines: {node: '>=10'} + /@google-cloud/paginator@5.0.0: + resolution: {integrity: sha512-87aeg6QQcEPxGCOthnpUjvw4xAZ57G7pL8FS0C4e/81fr3FjkpUpibf1s2v5XGyGhUVGF4Jfg7yEcxqn2iUw1w==} + engines: {node: '>=14.0.0'} requiresBuild: true dependencies: arrify: 2.0.1 @@ -1865,42 +1882,41 @@ packages: dev: false optional: true - /@google-cloud/projectify@3.0.0: - resolution: {integrity: sha512-HRkZsNmjScY6Li8/kb70wjGlDDyLkVk3KvoEo9uIoxSjYLJasGiCch9+PqRVDOCGUFvEIqyogl+BeqILL4OJHA==} - engines: {node: '>=12.0.0'} + /@google-cloud/projectify@4.0.0: + resolution: {integrity: sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==} + engines: {node: '>=14.0.0'} requiresBuild: true dev: false optional: true - /@google-cloud/promisify@3.0.1: - resolution: {integrity: sha512-z1CjRjtQyBOYL+5Qr9DdYIfrdLBe746jRTYfaYU6MeXkqp7UfYs/jX16lFFVzZ7PGEJvqZNqYUEtb1mvDww4pA==} - engines: {node: '>=12'} + /@google-cloud/promisify@4.0.0: + resolution: {integrity: sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==} + engines: {node: '>=14'} requiresBuild: true dev: false optional: true - /@google-cloud/storage@6.12.0: - resolution: {integrity: sha512-78nNAY7iiZ4O/BouWMWTD/oSF2YtYgYB3GZirn0To6eBOugjXVoK+GXgUXOl+HlqbAOyHxAVXOlsj3snfbQ1dw==} - engines: {node: '>=12'} + /@google-cloud/storage@7.7.0: + resolution: {integrity: sha512-EMCEY+6JiIkx7Dt8NXVGGjy1vRdSGdHkoqZoqjJw7cEBkT7ZkX0c7puedfn1MamnzW5SX4xoa2jVq5u7OWBmkQ==} + engines: {node: '>=14'} requiresBuild: true dependencies: - '@google-cloud/paginator': 3.0.7 - '@google-cloud/projectify': 3.0.0 - '@google-cloud/promisify': 3.0.1 + '@google-cloud/paginator': 5.0.0 + '@google-cloud/projectify': 4.0.0 + '@google-cloud/promisify': 4.0.0 abort-controller: 3.0.0 async-retry: 1.3.3 compressible: 2.0.18 duplexify: 4.1.2 ent: 2.2.0 - extend: 3.0.2 fast-xml-parser: 4.3.2 - gaxios: 5.1.3 - google-auth-library: 8.9.0 + gaxios: 6.1.1 + google-auth-library: 9.4.1 mime: 3.0.0 mime-types: 2.1.35 p-limit: 3.1.0 - retry-request: 5.0.2 - teeny-request: 8.0.3 + retry-request: 7.0.1 + teeny-request: 9.0.0 uuid: 8.3.2 transitivePeerDependencies: - encoding @@ -1918,7 +1934,7 @@ packages: tslib: 2.5.3 dev: true - /@graphql-codegen/cli@5.0.0(@types/node@20.9.3)(graphql@16.8.1)(typescript@5.3.2): + /@graphql-codegen/cli@5.0.0(@types/node@20.10.4)(graphql@16.8.1)(typescript@5.3.3): resolution: {integrity: sha512-A7J7+be/a6e+/ul2KI5sfJlpoqeqwX8EzktaKCeduyVKgOLA6W5t+NUGf6QumBDXU8PEOqXk3o3F+RAwCWOiqA==} hasBin: true peerDependencies: @@ -1936,20 +1952,20 @@ packages: '@graphql-tools/apollo-engine-loader': 8.0.0(graphql@16.8.1) '@graphql-tools/code-file-loader': 8.0.2(graphql@16.8.1) '@graphql-tools/git-loader': 8.0.2(graphql@16.8.1) - '@graphql-tools/github-loader': 8.0.0(@types/node@20.9.3)(graphql@16.8.1) + '@graphql-tools/github-loader': 8.0.0(@types/node@20.10.4)(graphql@16.8.1) '@graphql-tools/graphql-file-loader': 8.0.0(graphql@16.8.1) '@graphql-tools/json-file-loader': 8.0.0(graphql@16.8.1) '@graphql-tools/load': 8.0.0(graphql@16.8.1) - '@graphql-tools/prisma-loader': 8.0.1(@types/node@20.9.3)(graphql@16.8.1) - '@graphql-tools/url-loader': 8.0.0(@types/node@20.9.3)(graphql@16.8.1) + '@graphql-tools/prisma-loader': 8.0.1(@types/node@20.10.4)(graphql@16.8.1) + '@graphql-tools/url-loader': 8.0.0(@types/node@20.10.4)(graphql@16.8.1) '@graphql-tools/utils': 10.0.7(graphql@16.8.1) '@whatwg-node/fetch': 0.8.8 chalk: 4.1.2 - cosmiconfig: 8.3.6(typescript@5.3.2) + cosmiconfig: 8.3.6(typescript@5.3.3) debounce: 1.2.1 detect-indent: 6.1.0 graphql: 16.8.1 - graphql-config: 5.0.3(@types/node@20.9.3)(graphql@16.8.1)(typescript@5.3.2) + graphql-config: 5.0.3(@types/node@20.10.4)(graphql@16.8.1)(typescript@5.3.3) inquirer: 8.2.6 is-glob: 4.0.3 jiti: 1.20.0 @@ -2210,7 +2226,7 @@ packages: - utf-8-validate dev: true - /@graphql-tools/executor-http@1.0.3(@types/node@20.9.3)(graphql@16.8.1): + /@graphql-tools/executor-http@1.0.3(@types/node@20.10.4)(graphql@16.8.1): resolution: {integrity: sha512-5WZIMBevRaxMabZ8U2Ty0dTUPy/PpeYSlMNEmC/YJjKKykgSfc/AwSejx2sE4FFKZ0I2kxRKRenyoWMHRAV49Q==} engines: {node: '>=16.0.0'} peerDependencies: @@ -2221,7 +2237,7 @@ packages: '@whatwg-node/fetch': 0.9.13 extract-files: 11.0.0 graphql: 16.8.1 - meros: 1.3.0(@types/node@20.9.3) + meros: 1.3.0(@types/node@20.10.4) tslib: 2.6.2 value-or-promise: 1.0.12 transitivePeerDependencies: @@ -2276,14 +2292,14 @@ packages: - supports-color dev: true - /@graphql-tools/github-loader@8.0.0(@types/node@20.9.3)(graphql@16.8.1): + /@graphql-tools/github-loader@8.0.0(@types/node@20.10.4)(graphql@16.8.1): resolution: {integrity: sha512-VuroArWKcG4yaOWzV0r19ElVIV6iH6UKDQn1MXemND0xu5TzrFme0kf3U9o0YwNo0kUYEk9CyFM0BYg4he17FA==} engines: {node: '>=16.0.0'} peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 dependencies: '@ardatan/sync-fetch': 0.0.1 - '@graphql-tools/executor-http': 1.0.3(@types/node@20.9.3)(graphql@16.8.1) + '@graphql-tools/executor-http': 1.0.3(@types/node@20.10.4)(graphql@16.8.1) '@graphql-tools/graphql-tag-pluck': 8.0.2(graphql@16.8.1) '@graphql-tools/utils': 10.0.7(graphql@16.8.1) '@whatwg-node/fetch': 0.9.13 @@ -2405,13 +2421,13 @@ packages: tslib: 2.6.2 dev: true - /@graphql-tools/prisma-loader@8.0.1(@types/node@20.9.3)(graphql@16.8.1): + /@graphql-tools/prisma-loader@8.0.1(@types/node@20.10.4)(graphql@16.8.1): resolution: {integrity: sha512-bl6e5sAYe35Z6fEbgKXNrqRhXlCJYeWKBkarohgYA338/SD9eEhXtg3Cedj7fut3WyRLoQFpHzfiwxKs7XrgXg==} engines: {node: '>=16.0.0'} peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 dependencies: - '@graphql-tools/url-loader': 8.0.0(@types/node@20.9.3)(graphql@16.8.1) + '@graphql-tools/url-loader': 8.0.0(@types/node@20.10.4)(graphql@16.8.1) '@graphql-tools/utils': 10.0.7(graphql@16.8.1) '@types/js-yaml': 4.0.8 '@types/json-stable-stringify': 1.0.35 @@ -2491,7 +2507,7 @@ packages: value-or-promise: 1.0.12 dev: false - /@graphql-tools/url-loader@8.0.0(@types/node@20.9.3)(graphql@16.8.1): + /@graphql-tools/url-loader@8.0.0(@types/node@20.10.4)(graphql@16.8.1): resolution: {integrity: sha512-rPc9oDzMnycvz+X+wrN3PLrhMBQkG4+sd8EzaFN6dypcssiefgWKToXtRKI8HHK68n2xEq1PyrOpkjHFJB+GwA==} engines: {node: '>=16.0.0'} peerDependencies: @@ -2500,7 +2516,7 @@ packages: '@ardatan/sync-fetch': 0.0.1 '@graphql-tools/delegate': 10.0.3(graphql@16.8.1) '@graphql-tools/executor-graphql-ws': 1.1.0(graphql@16.8.1) - '@graphql-tools/executor-http': 1.0.3(@types/node@20.9.3)(graphql@16.8.1) + '@graphql-tools/executor-http': 1.0.3(@types/node@20.10.4)(graphql@16.8.1) '@graphql-tools/executor-legacy-ws': 1.0.4(graphql@16.8.1) '@graphql-tools/utils': 10.0.7(graphql@16.8.1) '@graphql-tools/wrap': 10.0.1(graphql@16.8.1) @@ -2593,13 +2609,13 @@ packages: dependencies: graphql: 16.8.1 - /@grpc/grpc-js@1.8.21: - resolution: {integrity: sha512-KeyQeZpxeEBSqFVTi3q2K7PiPXmgBfECc4updA1ejCLjYmoAlvvM3ZMp5ztTDUCUQmoY3CpDxvchjO1+rFkoHg==} + /@grpc/grpc-js@1.9.12: + resolution: {integrity: sha512-Um5MBuge32TS3lAKX02PGCnFM4xPT996yLgZNb5H03pn6NyJ4Iwn5YcPq6Jj9yxGRk7WOgaZFtVRH5iTdYBeUg==} engines: {node: ^8.13.0 || >=10.10.0} requiresBuild: true dependencies: '@grpc/proto-loader': 0.7.10 - '@types/node': 20.9.3 + '@types/node': 20.10.4 dev: false optional: true @@ -2636,6 +2652,194 @@ packages: resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==} dev: true + /@img/sharp-darwin-arm64@0.33.0: + resolution: {integrity: sha512-070tEheekI1LJWTGPC9WlQEa5UoKTXzzlORBHMX4TbfUxMiL336YHR8vBEUNsjse0RJCX8dZ4ZXwT595aEF1ug==} + engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.0.0 + dev: false + optional: true + + /@img/sharp-darwin-x64@0.33.0: + resolution: {integrity: sha512-pu/nvn152F3qbPeUkr+4e9zVvEhD3jhwzF473veQfMPkOYo9aoWXSfdZH/E6F+nYC3qvFjbxbvdDbUtEbghLqw==} + engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [x64] + os: [darwin] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.0.0 + dev: false + optional: true + + /@img/sharp-libvips-darwin-arm64@1.0.0: + resolution: {integrity: sha512-VzYd6OwnUR81sInf3alj1wiokY50DjsHz5bvfnsFpxs5tqQxESoHtJO6xyksDs3RIkyhMWq2FufXo6GNSU9BMw==} + engines: {macos: '>=11', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-darwin-x64@1.0.0: + resolution: {integrity: sha512-dD9OznTlHD6aovRswaPNEy8dKtSAmNo4++tO7uuR4o5VxbVAOoEQ1uSmN4iFAdQneTHws1lkTZeiXPrcCkh6IA==} + engines: {macos: '>=10.13', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-arm64@1.0.0: + resolution: {integrity: sha512-xTYThiqEZEZc0PRU90yVtM3KE7lw1bKdnDQ9kCTHWbqWyHOe4NpPOtMGy27YnN51q0J5dqRrvicfPbALIOeAZA==} + engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-arm@1.0.0: + resolution: {integrity: sha512-VwgD2eEikDJUk09Mn9Dzi1OW2OJFRQK+XlBTkUNmAWPrtj8Ly0yq05DFgu1VCMx2/DqCGQVi5A1dM9hTmxf3uw==} + engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-s390x@1.0.0: + resolution: {integrity: sha512-o9E46WWBC6JsBlwU4QyU9578G77HBDT1NInd+aERfxeOPbk0qBZHgoDsQmA2v9TbqJRWzoBPx1aLOhprBMgPjw==} + engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-x64@1.0.0: + resolution: {integrity: sha512-naldaJy4hSVhWBgEjfdBY85CAa4UO+W1nx6a1sWStHZ7EUfNiuBTTN2KUYT5dH1+p/xij1t2QSXfCiFJoC5S/Q==} + engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linuxmusl-arm64@1.0.0: + resolution: {integrity: sha512-OdorplCyvmSAPsoJLldtLh3nLxRrkAAAOHsGWGDYfN0kh730gifK+UZb3dWORRa6EusNqCTjfXV4GxvgJ/nPDQ==} + engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linuxmusl-x64@1.0.0: + resolution: {integrity: sha512-FW8iK6rJrg+X2jKD0Ajhjv6y74lToIBEvkZhl42nZt563FfxkCYacrXZtd+q/sRQDypQLzY5WdLkVTbJoPyqNg==} + engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-linux-arm64@0.33.0: + resolution: {integrity: sha512-dcomVSrtgF70SyOr8RCOCQ8XGVThXwe71A1d8MGA+mXEVRJ/J6/TrCbBEJh9ddcEIIsrnrkolaEvYSHqVhswQw==} + engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.0.0 + dev: false + optional: true + + /@img/sharp-linux-arm@0.33.0: + resolution: {integrity: sha512-4horD3wMFd5a0ddbDY8/dXU9CaOgHjEHALAddXgafoR5oWq5s8X61PDgsSeh4Qupsdo6ycfPPSSNBrfVQnwwrg==} + engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.0.0 + dev: false + optional: true + + /@img/sharp-linux-s390x@0.33.0: + resolution: {integrity: sha512-TiVJbx38J2rNVfA309ffSOB+3/7wOsZYQEOlKqOUdWD/nqkjNGrX+YQGz7nzcf5oy2lC+d37+w183iNXRZNngQ==} + engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [s390x] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.0.0 + dev: false + optional: true + + /@img/sharp-linux-x64@0.33.0: + resolution: {integrity: sha512-PaZM4Zi7/Ek71WgTdvR+KzTZpBqrQOFcPe7/8ZoPRlTYYRe43k6TWsf4GVH6XKRLMYeSp8J89RfAhBrSP4itNA==} + engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [x64] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.0.0 + dev: false + optional: true + + /@img/sharp-linuxmusl-arm64@0.33.0: + resolution: {integrity: sha512-1QLbbN0zt+32eVrg7bb1lwtvEaZwlhEsY1OrijroMkwAqlHqFj6R33Y47s2XUv7P6Ie1PwCxK/uFnNqMnkd5kg==} + engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.0.0 + dev: false + optional: true + + /@img/sharp-linuxmusl-x64@0.33.0: + resolution: {integrity: sha512-CecqgB/CnkvCWFhmfN9ZhPGMLXaEBXl4o7WtA6U3Ztrlh/s7FUKX4vNxpMSYLIrWuuzjiaYdfU3+Tdqh1xaHfw==} + engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [x64] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.0.0 + dev: false + optional: true + + /@img/sharp-wasm32@0.33.0: + resolution: {integrity: sha512-Hn4js32gUX9qkISlemZBUPuMs0k/xNJebUNl/L6djnU07B/HAA2KaxRVb3HvbU5fL242hLOcp0+tR+M8dvJUFw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [wasm32] + requiresBuild: true + dependencies: + '@emnapi/runtime': 0.44.0 + dev: false + optional: true + + /@img/sharp-win32-ia32@0.33.0: + resolution: {integrity: sha512-5HfcsCZi3l5nPRF2q3bllMVMDXBqEWI3Q8KQONfzl0TferFE5lnsIG0A1YrntMAGqvkzdW6y1Ci1A2uTvxhfzg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-win32-x64@0.33.0: + resolution: {integrity: sha512-i3DtP/2ce1yKFj4OzOnOYltOEL/+dp4dc4dJXJBv6god1AFTcmkaA99H/7SwOmkCOBQkbVvA3lCGm3/5nDtf9Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + /@ioredis/commands@1.2.0: resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==} @@ -2672,14 +2876,14 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.9.3 + '@types/node': 20.10.4 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 slash: 3.0.0 dev: true - /@jest/core@29.7.0(ts-node@10.9.1): + /@jest/core@29.7.0(ts-node@10.9.2): resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -2693,14 +2897,14 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.9.3 + '@types/node': 20.10.4 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.9.3)(ts-node@10.9.1) + jest-config: 29.7.0(@types/node@20.10.4)(ts-node@10.9.2) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -2735,7 +2939,7 @@ packages: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.9.3 + '@types/node': 20.10.4 jest-mock: 29.7.0 dev: true @@ -2762,7 +2966,7 @@ packages: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 20.9.3 + '@types/node': 20.10.4 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -2795,7 +2999,7 @@ packages: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.20 - '@types/node': 20.9.3 + '@types/node': 20.10.4 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 @@ -2882,7 +3086,7 @@ packages: dependencies: '@types/istanbul-lib-coverage': 2.0.5 '@types/istanbul-reports': 3.0.3 - '@types/node': 20.9.3 + '@types/node': 20.10.4 '@types/yargs': 16.0.7 chalk: 4.1.2 dev: true @@ -2894,7 +3098,7 @@ packages: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.5 '@types/istanbul-reports': 3.0.3 - '@types/node': 20.9.3 + '@types/node': 20.10.4 '@types/yargs': 17.0.29 chalk: 4.1.2 dev: true @@ -2948,15 +3152,6 @@ packages: resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} dev: false - /@jsdoc/salty@0.2.5: - resolution: {integrity: sha512-TfRP53RqunNe2HBobVBJ0VLhK1HbfvBYeTC1ahnN64PWvyYyGebmMiPkuwvD9fpw2ZbkoPb8Q7mwy0aR8Z9rvw==} - engines: {node: '>=v12.0.0'} - requiresBuild: true - dependencies: - lodash: 4.17.21 - dev: false - optional: true - /@lifeomic/attempt@3.0.3: resolution: {integrity: sha512-GlM2AbzrErd/TmLL3E8hAHmb5Q7VhDJp35vIbyPVA5Rz55LZuRr8pwL3qrwwkVNo05gMX1J44gURKb4MHQZo7w==} dev: false @@ -3006,9 +3201,9 @@ packages: '@apollo/server': 4.9.5(graphql@16.8.1) '@apollo/server-plugin-landing-page-graphql-playground': 4.0.0(@apollo/server@4.9.5) '@as-integrations/fastify': 2.1.1(@apollo/server@4.9.5)(fastify@4.24.3) - '@nestjs/common': 10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.13)(rxjs@7.8.1) - '@nestjs/core': 10.2.10(@nestjs/common@10.2.10)(@nestjs/microservices@10.2.10)(reflect-metadata@0.1.13)(rxjs@7.8.1) - '@nestjs/graphql': 12.0.11(@nestjs/common@10.2.10)(@nestjs/core@10.2.10)(class-validator@0.14.0)(graphql@16.8.1)(reflect-metadata@0.1.13) + '@nestjs/common': 10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/core': 10.2.10(@nestjs/common@10.2.10)(@nestjs/microservices@10.2.10)(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/graphql': 12.0.11(@nestjs/common@10.2.10)(@nestjs/core@10.2.10)(class-validator@0.14.0)(graphql@16.8.1)(reflect-metadata@0.1.14) graphql: 16.8.1 iterall: 1.3.0 lodash.omit: 4.5.0 @@ -3059,7 +3254,7 @@ packages: - webpack-cli dev: true - /@nestjs/common@10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.13)(rxjs@7.8.1): + /@nestjs/common@10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.14)(rxjs@7.8.1): resolution: {integrity: sha512-fwAk931rjW8CNH2Mgwawq/7HWHH1dxkOLdcgs7U52ddLk8CtHXjejm1cbNahewlSbNhvlOl7y1STLHutE6sUqw==} peerDependencies: class-transformer: '*' @@ -3074,12 +3269,12 @@ packages: dependencies: class-validator: 0.14.0 iterare: 1.2.1 - reflect-metadata: 0.1.13 + reflect-metadata: 0.1.14 rxjs: 7.8.1 tslib: 2.6.2 uid: 2.0.2 - /@nestjs/core@10.2.10(@nestjs/common@10.2.10)(@nestjs/microservices@10.2.10)(reflect-metadata@0.1.13)(rxjs@7.8.1): + /@nestjs/core@10.2.10(@nestjs/common@10.2.10)(@nestjs/microservices@10.2.10)(reflect-metadata@0.1.14)(rxjs@7.8.1): resolution: {integrity: sha512-+ckOI6BPi2ZMHikT9MCG4ctHDc4OnjhoIytrn7f2AYMMXI4bnutJhqyQKc30VDka5x3Wq6QAD57pgSP7y+JjJg==} requiresBuild: true peerDependencies: @@ -3097,13 +3292,13 @@ packages: '@nestjs/websockets': optional: true dependencies: - '@nestjs/common': 10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.13)(rxjs@7.8.1) - '@nestjs/microservices': 10.2.10(@nestjs/common@10.2.10)(@nestjs/core@10.2.10)(amqp-connection-manager@4.1.14)(amqplib@0.10.3)(ioredis@5.3.2)(reflect-metadata@0.1.13)(rxjs@7.8.1) + '@nestjs/common': 10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/microservices': 10.2.10(@nestjs/common@10.2.10)(@nestjs/core@10.2.10)(amqp-connection-manager@4.1.14)(amqplib@0.10.3)(ioredis@5.3.2)(reflect-metadata@0.1.14)(rxjs@7.8.1) '@nuxtjs/opencollective': 0.3.2 fast-safe-stringify: 2.1.1 iterare: 1.2.1 path-to-regexp: 3.2.0 - reflect-metadata: 0.1.13 + reflect-metadata: 0.1.14 rxjs: 7.8.1 tslib: 2.6.2 uid: 2.0.2 @@ -3118,11 +3313,11 @@ packages: rxjs: ^7.2.0 dependencies: '@elastic/elasticsearch': 8.10.0 - '@nestjs/common': 10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.13)(rxjs@7.8.1) + '@nestjs/common': 10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.14)(rxjs@7.8.1) rxjs: 7.8.1 dev: false - /@nestjs/graphql@12.0.11(@nestjs/common@10.2.10)(@nestjs/core@10.2.10)(class-validator@0.14.0)(graphql@16.8.1)(reflect-metadata@0.1.13): + /@nestjs/graphql@12.0.11(@nestjs/common@10.2.10)(@nestjs/core@10.2.10)(class-validator@0.14.0)(graphql@16.8.1)(reflect-metadata@0.1.14): resolution: {integrity: sha512-iCyVs9+utCQt9ehMhUjQcEdjRN/MrcTBINd7P44O1fzGENuWMbt1Z8RCoZbeGi5iVPBY63HgYik+BnnICqmxZw==} peerDependencies: '@apollo/subgraph': ^2.0.0 @@ -3146,9 +3341,9 @@ packages: '@graphql-tools/merge': 9.0.0(graphql@16.8.1) '@graphql-tools/schema': 10.0.0(graphql@16.8.1) '@graphql-tools/utils': 10.0.8(graphql@16.8.1) - '@nestjs/common': 10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.13)(rxjs@7.8.1) - '@nestjs/core': 10.2.10(@nestjs/common@10.2.10)(@nestjs/microservices@10.2.10)(reflect-metadata@0.1.13)(rxjs@7.8.1) - '@nestjs/mapped-types': 2.0.2(@nestjs/common@10.2.10)(class-validator@0.14.0)(reflect-metadata@0.1.13) + '@nestjs/common': 10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/core': 10.2.10(@nestjs/common@10.2.10)(@nestjs/microservices@10.2.10)(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/mapped-types': 2.0.2(@nestjs/common@10.2.10)(class-validator@0.14.0)(reflect-metadata@0.1.14) chokidar: 3.5.3 class-validator: 0.14.0 fast-glob: 3.3.2 @@ -3157,7 +3352,7 @@ packages: graphql-ws: 5.14.2(graphql@16.8.1) lodash: 4.17.21 normalize-path: 3.0.0 - reflect-metadata: 0.1.13 + reflect-metadata: 0.1.14 subscriptions-transport-ws: 0.11.0(graphql@16.8.1) tslib: 2.6.2 uuid: 9.0.1 @@ -3172,12 +3367,12 @@ packages: peerDependencies: '@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0 dependencies: - '@nestjs/common': 10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.13)(rxjs@7.8.1) + '@nestjs/common': 10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.14)(rxjs@7.8.1) '@types/jsonwebtoken': 9.0.5 jsonwebtoken: 9.0.2 dev: false - /@nestjs/mapped-types@2.0.2(@nestjs/common@10.2.10)(class-validator@0.14.0)(reflect-metadata@0.1.13): + /@nestjs/mapped-types@2.0.2(@nestjs/common@10.2.10)(class-validator@0.14.0)(reflect-metadata@0.1.14): resolution: {integrity: sha512-V0izw6tWs6fTp9+KiiPUbGHWALy563Frn8X6Bm87ANLRuE46iuBMD5acKBDP5lKL/75QFvrzSJT7HkCbB0jTpg==} peerDependencies: '@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0 @@ -3190,12 +3385,12 @@ packages: class-validator: optional: true dependencies: - '@nestjs/common': 10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.13)(rxjs@7.8.1) + '@nestjs/common': 10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.14)(rxjs@7.8.1) class-validator: 0.14.0 - reflect-metadata: 0.1.13 + reflect-metadata: 0.1.14 dev: false - /@nestjs/mapped-types@2.0.3(@nestjs/common@10.2.10)(class-validator@0.14.0)(reflect-metadata@0.1.13): + /@nestjs/mapped-types@2.0.3(@nestjs/common@10.2.10)(class-validator@0.14.0)(reflect-metadata@0.1.14): resolution: {integrity: sha512-40Zdqg98lqoF0+7ThWIZFStxgzisK6GG22+1ABO4kZiGF/Tu2FE+DYLw+Q9D94vcFWizJ+MSjNN4ns9r6hIGxw==} peerDependencies: '@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0 @@ -3208,12 +3403,12 @@ packages: class-validator: optional: true dependencies: - '@nestjs/common': 10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.13)(rxjs@7.8.1) + '@nestjs/common': 10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.14)(rxjs@7.8.1) class-validator: 0.14.0 - reflect-metadata: 0.1.13 + reflect-metadata: 0.1.14 dev: false - /@nestjs/microservices@10.2.10(@nestjs/common@10.2.10)(@nestjs/core@10.2.10)(amqp-connection-manager@4.1.14)(amqplib@0.10.3)(ioredis@5.3.2)(reflect-metadata@0.1.13)(rxjs@7.8.1): + /@nestjs/microservices@10.2.10(@nestjs/common@10.2.10)(@nestjs/core@10.2.10)(amqp-connection-manager@4.1.14)(amqplib@0.10.3)(ioredis@5.3.2)(reflect-metadata@0.1.14)(rxjs@7.8.1): resolution: {integrity: sha512-vebXc4lF67grtLr3UXc+rPErH5aCzCez1Y2Oec4k2K4ObhjftNug7L2O9W3XiprHlwPhPXc51VQ9nhKn7IFAxw==} peerDependencies: '@grpc/grpc-js': '*' @@ -3249,24 +3444,24 @@ packages: nats: optional: true dependencies: - '@nestjs/common': 10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.13)(rxjs@7.8.1) - '@nestjs/core': 10.2.10(@nestjs/common@10.2.10)(@nestjs/microservices@10.2.10)(reflect-metadata@0.1.13)(rxjs@7.8.1) + '@nestjs/common': 10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/core': 10.2.10(@nestjs/common@10.2.10)(@nestjs/microservices@10.2.10)(reflect-metadata@0.1.14)(rxjs@7.8.1) amqp-connection-manager: 4.1.14(amqplib@0.10.3) amqplib: 0.10.3 ioredis: 5.3.2 iterare: 1.2.1 - reflect-metadata: 0.1.13 + reflect-metadata: 0.1.14 rxjs: 7.8.1 tslib: 2.6.2 - /@nestjs/passport@10.0.2(@nestjs/common@10.2.10)(passport@0.6.0): - resolution: {integrity: sha512-od31vfB2z3y05IDB5dWSbCGE2+pAf2k2WCBinNuTTOxN0O0+wtO1L3kawj/aCW3YR9uxsTOVbTDwtwgpNNsnjQ==} + /@nestjs/passport@10.0.3(@nestjs/common@10.2.10)(passport@0.7.0): + resolution: {integrity: sha512-znJ9Y4S8ZDVY+j4doWAJ8EuuVO7SkQN3yOBmzxbGaXbvcSwFDAdGJ+OMCg52NdzIO4tQoN4pYKx8W6M0ArfFRQ==} peerDependencies: '@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0 - passport: ^0.4.0 || ^0.5.0 || ^0.6.0 + passport: ^0.4.0 || ^0.5.0 || ^0.6.0 || ^0.7.0 dependencies: - '@nestjs/common': 10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.13)(rxjs@7.8.1) - passport: 0.6.0 + '@nestjs/common': 10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.14)(rxjs@7.8.1) + passport: 0.7.0 dev: false /@nestjs/platform-fastify@10.2.10(@fastify/static@6.12.0)(@nestjs/common@10.2.10)(@nestjs/core@10.2.10): @@ -3286,8 +3481,8 @@ packages: '@fastify/formbody': 7.4.0 '@fastify/middie': 8.3.0 '@fastify/static': 6.12.0 - '@nestjs/common': 10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.13)(rxjs@7.8.1) - '@nestjs/core': 10.2.10(@nestjs/common@10.2.10)(@nestjs/microservices@10.2.10)(reflect-metadata@0.1.13)(rxjs@7.8.1) + '@nestjs/common': 10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/core': 10.2.10(@nestjs/common@10.2.10)(@nestjs/microservices@10.2.10)(reflect-metadata@0.1.14)(rxjs@7.8.1) fastify: 4.24.3 light-my-request: 5.11.0 path-to-regexp: 3.2.0 @@ -3296,17 +3491,17 @@ packages: - supports-color dev: false - /@nestjs/schedule@4.0.0(@nestjs/common@10.2.10)(@nestjs/core@10.2.10)(reflect-metadata@0.1.13): + /@nestjs/schedule@4.0.0(@nestjs/common@10.2.10)(@nestjs/core@10.2.10)(reflect-metadata@0.1.14): resolution: {integrity: sha512-zz4h54m/F/1qyQKvMJCRphmuwGqJltDAkFxUXCVqJBXEs5kbPt93Pza3heCQOcMH22MZNhGlc9DmDMLXVHmgVQ==} peerDependencies: '@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0 '@nestjs/core': ^8.0.0 || ^9.0.0 || ^10.0.0 reflect-metadata: ^0.1.12 dependencies: - '@nestjs/common': 10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.13)(rxjs@7.8.1) - '@nestjs/core': 10.2.10(@nestjs/common@10.2.10)(@nestjs/microservices@10.2.10)(reflect-metadata@0.1.13)(rxjs@7.8.1) + '@nestjs/common': 10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/core': 10.2.10(@nestjs/common@10.2.10)(@nestjs/microservices@10.2.10)(reflect-metadata@0.1.14)(rxjs@7.8.1) cron: 3.1.3 - reflect-metadata: 0.1.13 + reflect-metadata: 0.1.14 uuid: 9.0.1 dev: false @@ -3325,7 +3520,7 @@ packages: - chokidar dev: true - /@nestjs/schematics@10.0.3(typescript@5.3.2): + /@nestjs/schematics@10.0.3(typescript@5.3.3): resolution: {integrity: sha512-2BRujK0GqGQ7j1Zpz+obVfskDnnOeVKt5aXoSaVngKo8Oczy8uYCY+R547TQB+Kf35epdfFER2pVnQrX3/It5A==} peerDependencies: typescript: '>=4.8.2' @@ -3335,12 +3530,12 @@ packages: comment-json: 4.2.3 jsonc-parser: 3.2.0 pluralize: 8.0.0 - typescript: 5.3.2 + typescript: 5.3.3 transitivePeerDependencies: - chokidar dev: true - /@nestjs/swagger@7.1.16(@fastify/static@6.12.0)(@nestjs/common@10.2.10)(@nestjs/core@10.2.10)(class-validator@0.14.0)(reflect-metadata@0.1.13): + /@nestjs/swagger@7.1.16(@fastify/static@6.12.0)(@nestjs/common@10.2.10)(@nestjs/core@10.2.10)(class-validator@0.14.0)(reflect-metadata@0.1.14): resolution: {integrity: sha512-f9KBk/BX9MUKPTj7tQNYJ124wV/jP5W2lwWHLGwe/4qQXixuDOo39zP55HIJ44LE7S04B7BOeUOo9GBJD/vRcw==} peerDependencies: '@fastify/static': ^6.0.0 @@ -3358,14 +3553,14 @@ packages: optional: true dependencies: '@fastify/static': 6.12.0 - '@nestjs/common': 10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.13)(rxjs@7.8.1) - '@nestjs/core': 10.2.10(@nestjs/common@10.2.10)(@nestjs/microservices@10.2.10)(reflect-metadata@0.1.13)(rxjs@7.8.1) - '@nestjs/mapped-types': 2.0.3(@nestjs/common@10.2.10)(class-validator@0.14.0)(reflect-metadata@0.1.13) + '@nestjs/common': 10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/core': 10.2.10(@nestjs/common@10.2.10)(@nestjs/microservices@10.2.10)(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/mapped-types': 2.0.3(@nestjs/common@10.2.10)(class-validator@0.14.0)(reflect-metadata@0.1.14) class-validator: 0.14.0 js-yaml: 4.1.0 lodash: 4.17.21 path-to-regexp: 3.2.0 - reflect-metadata: 0.1.13 + reflect-metadata: 0.1.14 swagger-ui-dist: 5.9.1 dev: false @@ -3382,13 +3577,13 @@ packages: '@nestjs/platform-express': optional: true dependencies: - '@nestjs/common': 10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.13)(rxjs@7.8.1) - '@nestjs/core': 10.2.10(@nestjs/common@10.2.10)(@nestjs/microservices@10.2.10)(reflect-metadata@0.1.13)(rxjs@7.8.1) - '@nestjs/microservices': 10.2.10(@nestjs/common@10.2.10)(@nestjs/core@10.2.10)(amqp-connection-manager@4.1.14)(amqplib@0.10.3)(ioredis@5.3.2)(reflect-metadata@0.1.13)(rxjs@7.8.1) + '@nestjs/common': 10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/core': 10.2.10(@nestjs/common@10.2.10)(@nestjs/microservices@10.2.10)(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/microservices': 10.2.10(@nestjs/common@10.2.10)(@nestjs/core@10.2.10)(amqp-connection-manager@4.1.14)(amqplib@0.10.3)(ioredis@5.3.2)(reflect-metadata@0.1.14)(rxjs@7.8.1) tslib: 2.6.2 dev: true - /@nestjs/typeorm@10.0.1(@nestjs/common@10.2.10)(@nestjs/core@10.2.10)(reflect-metadata@0.1.13)(rxjs@7.8.1)(typeorm@0.3.17): + /@nestjs/typeorm@10.0.1(@nestjs/common@10.2.10)(@nestjs/core@10.2.10)(reflect-metadata@0.1.14)(rxjs@7.8.1)(typeorm@0.3.17): resolution: {integrity: sha512-YVFYL7D25VAVp5/G+KLXIgsRfYomA+VaFZBpm2rtwrrBOmkXNrxr7kuI2bBBO/Xy4kKBDe6wbvIVVFeEA7/ngA==} peerDependencies: '@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0 @@ -3397,11 +3592,11 @@ packages: rxjs: ^7.2.0 typeorm: ^0.3.0 dependencies: - '@nestjs/common': 10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.13)(rxjs@7.8.1) - '@nestjs/core': 10.2.10(@nestjs/common@10.2.10)(@nestjs/microservices@10.2.10)(reflect-metadata@0.1.13)(rxjs@7.8.1) - reflect-metadata: 0.1.13 + '@nestjs/common': 10.2.10(class-validator@0.14.0)(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/core': 10.2.10(@nestjs/common@10.2.10)(@nestjs/microservices@10.2.10)(reflect-metadata@0.1.14)(rxjs@7.8.1) + reflect-metadata: 0.1.14 rxjs: 7.8.1 - typeorm: 0.3.17(ioredis@5.3.2)(pg@8.11.3)(ts-node@10.9.1) + typeorm: 0.3.17(ioredis@5.3.2)(pg@8.11.3)(ts-node@10.9.2) uuid: 9.0.1 dev: false @@ -3487,15 +3682,15 @@ packages: dev: true optional: true - /@powerfulyang/lint@3.7.0(@types/node@20.9.3)(ts-node@10.9.1)(typescript@5.3.2): + /@powerfulyang/lint@3.7.0(@types/node@20.10.4)(ts-node@10.9.2)(typescript@5.3.3): resolution: {integrity: sha512-nSoBG8MzF0dIMuCOgR0fFseKheHbH+fZc9iXkcTUEn8GjauWqwEP75jH93o5CKF+Eui9fnpf8DgAJZkx3jc3QA==} dependencies: '@commitlint/cli': 17.8.1(@swc/core@1.3.94) '@commitlint/config-conventional': 17.8.1 '@swc/core': 1.3.94 '@swc/jest': 0.2.29(@swc/core@1.3.94) - '@typescript-eslint/eslint-plugin': 6.8.0(@typescript-eslint/parser@6.8.0)(eslint@8.52.0)(typescript@5.3.2) - '@typescript-eslint/parser': 6.8.0(eslint@8.52.0)(typescript@5.3.2) + '@typescript-eslint/eslint-plugin': 6.8.0(@typescript-eslint/parser@6.8.0)(eslint@8.52.0)(typescript@5.3.3) + '@typescript-eslint/parser': 6.8.0(eslint@8.52.0)(typescript@5.3.3) autoprefixer: 10.4.16(postcss@8.4.31) cross-env: 7.0.3 eslint: 8.52.0 @@ -3505,13 +3700,13 @@ packages: eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.8.0)(eslint-plugin-import@2.28.1)(eslint@8.52.0) eslint-plugin-eslint-comments: 3.2.0(eslint@8.52.0) eslint-plugin-import: 2.28.1(@typescript-eslint/parser@6.8.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.52.0) - eslint-plugin-jest: 27.4.3(@typescript-eslint/eslint-plugin@6.8.0)(eslint@8.52.0)(jest@29.7.0)(typescript@5.3.2) + eslint-plugin-jest: 27.4.3(@typescript-eslint/eslint-plugin@6.8.0)(eslint@8.52.0)(jest@29.7.0)(typescript@5.3.3) eslint-plugin-jsx-a11y: 6.7.1(eslint@8.52.0) eslint-plugin-react: 7.33.2(eslint@8.52.0) eslint-plugin-react-hooks: 4.6.0(eslint@8.52.0) eslint-plugin-unicorn: 48.0.1(eslint@8.52.0) husky: 8.0.3 - jest: 29.7.0(@types/node@20.9.3)(ts-node@10.9.1) + jest: 29.7.0(@types/node@20.10.4)(ts-node@10.9.2) jest-environment-jsdom: 29.7.0 lint-staged: 13.3.0 npm-run-all: 4.1.5 @@ -3521,7 +3716,7 @@ packages: prettier-plugin-tailwindcss: 0.4.1(prettier@3.0.3) rimraf: 5.0.5 sass: 1.69.4 - stylelint: 15.11.0(typescript@5.3.2) + stylelint: 15.11.0(typescript@5.3.3) stylelint-config-css-modules: 4.3.0(stylelint@15.11.0) stylelint-config-standard: 34.0.0(stylelint@15.11.0) stylelint-declaration-block-no-ignored-properties: 2.7.0(stylelint@15.11.0) @@ -3562,14 +3757,14 @@ packages: - utf-8-validate dev: true - /@powerfulyang/node-utils@1.6.0(sharp@0.32.6): + /@powerfulyang/node-utils@1.6.0(sharp@0.33.0): resolution: {integrity: sha512-BdAN+onCH1aw9od+wDFgBzbxrG8vUW99SR8XjQ0E4grxwjz/cudxpQH+dqM7AfjKKDl2LxHOCYOopA9SIYQE5A==} peerDependencies: sharp: ~0.31.3 || ~0.32.0 dependencies: '@powerfulyang/utils': 1.11.2 piscina: 4.0.0 - sharp: 0.32.6 + sharp: 0.33.0 transitivePeerDependencies: - supports-color dev: false @@ -3618,8 +3813,8 @@ packages: - supports-color dev: false - /@prisma/client@5.6.0(prisma@5.6.0): - resolution: {integrity: sha512-mUDefQFa1wWqk4+JhKPYq8BdVoFk9NFMBXUI8jAkBfQTtgx8WPx02U2HB/XbAz3GSUJpeJOKJQtNvaAIDs6sug==} + /@prisma/client@5.7.0(prisma@5.7.0): + resolution: {integrity: sha512-cZmglCrfNbYpzUtz7HscVHl38e9CrUs31nrVoGUK1nIPXGgt8hT4jj2s657UXcNdQ/jBUxDgGmHyu2Nyrq1txg==} engines: {node: '>=16.13'} requiresBuild: true peerDependencies: @@ -3628,17 +3823,35 @@ packages: prisma: optional: true dependencies: - '@prisma/engines-version': 5.6.0-32.e95e739751f42d8ca026f6b910f5a2dc5adeaeee - prisma: 5.6.0 + prisma: 5.7.0 dev: false - /@prisma/engines-version@5.6.0-32.e95e739751f42d8ca026f6b910f5a2dc5adeaeee: - resolution: {integrity: sha512-UoFgbV1awGL/3wXuUK3GDaX2SolqczeeJ5b4FVec9tzeGbSWJboPSbT0psSrmgYAKiKnkOPFSLlH6+b+IyOwAw==} - dev: false + /@prisma/debug@5.7.0: + resolution: {integrity: sha512-tZ+MOjWlVvz1kOEhNYMa4QUGURY+kgOUBqLHYIV8jmCsMuvA1tWcn7qtIMLzYWCbDcQT4ZS8xDgK0R2gl6/0wA==} + + /@prisma/engines-version@5.7.0-41.79fb5193cf0a8fdbef536e4b4a159cad677ab1b9: + resolution: {integrity: sha512-V6tgRVi62jRwTm0Hglky3Scwjr/AKFBFtS+MdbsBr7UOuiu1TKLPc6xfPiyEN1+bYqjEtjxwGsHgahcJsd1rNg==} - /@prisma/engines@5.6.0: - resolution: {integrity: sha512-Mt2q+GNJpU2vFn6kif24oRSBQv1KOkYaterQsi0k2/lA+dLvhRX6Lm26gon6PYHwUM8/h8KRgXIUMU0PCLB6bw==} + /@prisma/engines@5.7.0: + resolution: {integrity: sha512-TkOMgMm60n5YgEKPn9erIvFX2/QuWnl3GBo6yTRyZKk5O5KQertXiNnrYgSLy0SpsKmhovEPQb+D4l0SzyE7XA==} requiresBuild: true + dependencies: + '@prisma/debug': 5.7.0 + '@prisma/engines-version': 5.7.0-41.79fb5193cf0a8fdbef536e4b4a159cad677ab1b9 + '@prisma/fetch-engine': 5.7.0 + '@prisma/get-platform': 5.7.0 + + /@prisma/fetch-engine@5.7.0: + resolution: {integrity: sha512-zIn/qmO+N/3FYe7/L9o+yZseIU8ivh4NdPKSkQRIHfg2QVTVMnbhGoTcecbxfVubeTp+DjcbjS0H9fCuM4W04w==} + dependencies: + '@prisma/debug': 5.7.0 + '@prisma/engines-version': 5.7.0-41.79fb5193cf0a8fdbef536e4b4a159cad677ab1b9 + '@prisma/get-platform': 5.7.0 + + /@prisma/get-platform@5.7.0: + resolution: {integrity: sha512-ZeV/Op4bZsWXuw5Tg05WwRI8BlKiRFhsixPcAM+5BKYSiUZiMKIi713tfT3drBq8+T0E1arNZgYSA9QYcglWNA==} + dependencies: + '@prisma/debug': 5.7.0 /@protobufjs/aspromise@1.1.2: resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} @@ -3918,14 +4131,14 @@ packages: resolution: {integrity: sha512-N7UDG0/xiPQa2D/XrVJXjkWbpqHCd2sBaB32ggRF2l83RhPfamgKGF8gwwqyksS95qUS5ZYF9aF+lLPRlwI2UA==} dependencies: '@types/connect': 3.4.37 - '@types/node': 20.9.3 + '@types/node': 20.10.4 /@types/cacheable-request@6.0.3: resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} dependencies: '@types/http-cache-semantics': 4.0.3 '@types/keyv': 3.1.4 - '@types/node': 20.9.3 + '@types/node': 20.10.4 '@types/responselike': 1.0.2 dev: true @@ -3939,13 +4152,13 @@ packages: /@types/cls-hooked@4.3.8: resolution: {integrity: sha512-tf/7H883gFA6MPlWI15EQtfNZ+oPL0gLKkOlx9UHFrun1fC/FkuyNBpTKq1B5E3T4fbvjId6WifHUdSGsMMuPg==} dependencies: - '@types/node': 20.9.3 + '@types/node': 20.10.4 dev: true /@types/connect@3.4.37: resolution: {integrity: sha512-zBUSRqkfZ59OcwXon4HVxhx5oWCJmc0OtBTK05M+p0dYjgN6iTwIL2T/WbsQZrEsdnwaF9cWQ+azOnpPvIqY3Q==} dependencies: - '@types/node': 20.9.3 + '@types/node': 20.10.4 /@types/debug@4.1.10: resolution: {integrity: sha512-tOSCru6s732pofZ+sMv9o4o3Zc+Sa8l3bxd/tweTQudFn06vAzb13ZX46Zi6m6EJ+RUbRTHvgQJ1gBtSgkaUYA==} @@ -3974,7 +4187,7 @@ packages: /@types/express-serve-static-core@4.17.39: resolution: {integrity: sha512-BiEUfAiGCOllomsRAZOiMFP7LAnrifHpt56pc4Z7l9K6ACyN06Ns1JLMBxwkfLOjJRlSf06NwWsT7yzfpaVpyQ==} dependencies: - '@types/node': 20.9.3 + '@types/node': 20.10.4 '@types/qs': 6.9.9 '@types/range-parser': 1.2.6 '@types/send': 0.17.3 @@ -3995,22 +4208,13 @@ packages: resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} dependencies: '@types/jsonfile': 6.1.3 - '@types/node': 20.9.3 + '@types/node': 20.10.4 dev: true - /@types/glob@8.1.0: - resolution: {integrity: sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==} - requiresBuild: true - dependencies: - '@types/minimatch': 5.1.2 - '@types/node': 20.9.3 - dev: false - optional: true - /@types/graceful-fs@4.1.8: resolution: {integrity: sha512-NhRH7YzWq8WiNKVavKPBmtLYZHxNY19Hh+az28O/phfp68CF45pMFud+ZzJ8ewnxnC5smIdF3dqFeiSUQ5I+pw==} dependencies: - '@types/node': 20.9.3 + '@types/node': 20.10.4 dev: true /@types/hast@2.3.7: @@ -4055,7 +4259,7 @@ packages: /@types/jsdom@20.0.1: resolution: {integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==} dependencies: - '@types/node': 20.9.3 + '@types/node': 20.10.4 '@types/tough-cookie': 4.0.4 parse5: 7.1.2 dev: true @@ -4075,32 +4279,27 @@ packages: /@types/jsonfile@6.1.3: resolution: {integrity: sha512-/yqTk2SZ1wIezK0hiRZD7RuSf4B3whFxFamB1kGStv+8zlWScTMcHanzfc0XKWs5vA1TkHeckBlOyM8jxU8nHA==} dependencies: - '@types/node': 20.9.3 + '@types/node': 20.10.4 dev: true /@types/jsonwebtoken@9.0.4: resolution: {integrity: sha512-8UYapdmR0QlxgvJmyE8lP7guxD0UGVMfknsdtCFZh4ovShdBl3iOI4zdvqBHrB/IS+xUj3PSx73Qkey1fhWz+g==} dependencies: - '@types/node': 20.9.3 + '@types/node': 20.10.4 + dev: true /@types/jsonwebtoken@9.0.5: resolution: {integrity: sha512-VRLSGzik+Unrup6BsouBeHsf4d1hOEgYWTm/7Nmw1sXoN1+tRly/Gy/po3yeahnP4jfnQWWAhQAqcNfH7ngOkA==} dependencies: - '@types/node': 20.9.3 + '@types/node': 20.10.4 dev: false /@types/keyv@3.1.4: resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} dependencies: - '@types/node': 20.9.3 + '@types/node': 20.10.4 dev: true - /@types/linkify-it@3.0.4: - resolution: {integrity: sha512-hPpIeeHb/2UuCw06kSNAOVWgehBLXEo0/fUs0mw3W2qhqX89PI2yvok83MnuctYGCPrabGIoi0fFso4DQ+sNUQ==} - requiresBuild: true - dev: false - optional: true - /@types/lodash@4.14.202: resolution: {integrity: sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==} dev: true @@ -4113,15 +4312,6 @@ packages: resolution: {integrity: sha512-/BJF3NT0pRMuxrenr42emRUF67sXwcZCd+S1ksG/Fcf9O7C3kKCY4uJSbKBE4KDUIYr3WMsvfmWD8hRjXExBJQ==} dev: false - /@types/markdown-it@12.2.3: - resolution: {integrity: sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==} - requiresBuild: true - dependencies: - '@types/linkify-it': 3.0.4 - '@types/mdurl': 1.0.4 - dev: false - optional: true - /@types/mdast@3.0.14: resolution: {integrity: sha512-gVZ04PGgw1qLZKsnWnyFv4ORnaJ+DXLdHTVSFbU8yX6xZ34Bjg4Q32yPkmveUP1yItXReKfB0Aknlh/3zxTKAw==} dependencies: @@ -4134,24 +4324,12 @@ packages: '@types/unist': 3.0.1 dev: false - /@types/mdurl@1.0.4: - resolution: {integrity: sha512-ARVxjAEX5TARFRzpDRVC6cEk0hUIXCCwaMhz8y7S1/PxU6zZS1UMjyobz7q4w/D/R552r4++EhwmXK1N2rAy0A==} - requiresBuild: true - dev: false - optional: true - /@types/mime@1.3.4: resolution: {integrity: sha512-1Gjee59G25MrQGk8bsNvC6fxNiRgUlGn2wlhGf95a59DrprnnHk80FIMMFG9XHMdrfsuA119ht06QPDXA1Z7tw==} /@types/mime@3.0.3: resolution: {integrity: sha512-i8MBln35l856k5iOhKk2XJ4SeAWg75mLIpZB4v6imOagKL6twsukBZGDMNhdOVk7yRFTMPpfILocMos59Q1otQ==} - /@types/minimatch@5.1.2: - resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} - requiresBuild: true - dev: false - optional: true - /@types/minimist@1.2.4: resolution: {integrity: sha512-Kfe/D3hxHTusnPNRbycJE1N77WHDsdS4AjUYIzlDzhDrS47NrwuL3YW4VITxwR7KCVpzwgy4Rbj829KSSQmwXQ==} dev: true @@ -4163,29 +4341,29 @@ packages: /@types/node-fetch@2.6.9: resolution: {integrity: sha512-bQVlnMLFJ2d35DkPNjEPmd9ueO/rh5EiaZt2bhqiSarPjZIuIV6bPQVqcrEyvNo+AfTrRGVazle1tl597w3gfA==} dependencies: - '@types/node': 20.9.3 + '@types/node': 20.10.4 form-data: 4.0.0 - /@types/node-telegram-bot-api@0.63.3: - resolution: {integrity: sha512-K0uo0em5IBqMqUrQ8l6bFgvlrFCyd6FLjVmn9xux7R/71kMDrNutCp8nd1WSaNp2D782JWcf0dbiS5iJofzOTw==} + /@types/node-telegram-bot-api@0.64.0: + resolution: {integrity: sha512-iSfOaHWIAD2XgHqM5/hkoRztYEYHQ7aNr8Kgq+BBjXtIT00WqhZuLVn3Pmv44h1L3bNDxqSqNk1B42XDDoe5zA==} dependencies: - '@types/node': 20.9.3 + '@types/node': 20.10.4 '@types/request': 2.48.11 dev: true + /@types/node@20.10.4: + resolution: {integrity: sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==} + dependencies: + undici-types: 5.26.5 + /@types/node@20.5.1: resolution: {integrity: sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==} dev: true - /@types/node@20.9.3: - resolution: {integrity: sha512-nk5wXLAXGBKfrhLB0cyHGbSqopS+nz0BUgZkUQqSHSSgdee0kssp1IAqlQOu333bW+gMNs2QREx7iynm19Abxw==} - dependencies: - undici-types: 5.26.5 - /@types/nodemailer@6.4.14: resolution: {integrity: sha512-fUWthHO9k9DSdPCSPRqcu6TWhYyxTBg382vlNIttSe9M7XfsT06y0f24KHXtbnijPGGRIcVvdKHTNikOI6qiHA==} dependencies: - '@types/node': 20.9.3 + '@types/node': 20.10.4 dev: true /@types/normalize-package-data@2.4.3: @@ -4195,7 +4373,7 @@ packages: /@types/oauth@0.9.3: resolution: {integrity: sha512-avZiwxSz/WS6EaEjhchzXKgWtlGGYGnEVJoHuQuDLHf7gIW1Gmm9eIxOMuJ6umQNNKZkJ3Uy+C/rLzEvL3I8Sw==} dependencies: - '@types/node': 20.9.3 + '@types/node': 20.10.4 dev: true /@types/passport-github@1.1.12: @@ -4260,25 +4438,16 @@ packages: resolution: {integrity: sha512-HuihY1+Vss5RS9ZHzRyTGIzwPTdrJBkCm/mAeLRYrOQu/MGqyezKXWOK1VhCnR+SDbp9G2mRUP+OVEqCrzpcfA==} dependencies: '@types/caseless': 0.12.4 - '@types/node': 20.9.3 + '@types/node': 20.10.4 '@types/tough-cookie': 4.0.4 form-data: 2.5.1 /@types/responselike@1.0.2: resolution: {integrity: sha512-/4YQT5Kp6HxUDb4yhRkm0bJ7TbjvTddqX7PZ5hz6qV3pxSo72f/6YPRo+Mu2DU307tm9IioO69l7uAwn5XNcFA==} dependencies: - '@types/node': 20.9.3 + '@types/node': 20.10.4 dev: true - /@types/rimraf@3.0.2: - resolution: {integrity: sha512-F3OznnSLAUxFrCEu/L5PY8+ny8DtcFRjx7fZZ9bycvXRi3KPTRS9HOitGZwvPg0juRhXFWIeKX58cnX5YqLohQ==} - requiresBuild: true - dependencies: - '@types/glob': 8.1.0 - '@types/node': 20.9.3 - dev: false - optional: true - /@types/semver@7.5.4: resolution: {integrity: sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==} dev: true @@ -4287,19 +4456,19 @@ packages: resolution: {integrity: sha512-/7fKxvKUoETxjFUsuFlPB9YndePpxxRAOfGC/yJdc9kTjTeP5kRCTzfnE8kPUKCeyiyIZu0YQ76s50hCedI1ug==} dependencies: '@types/mime': 1.3.4 - '@types/node': 20.9.3 + '@types/node': 20.10.4 /@types/serve-static@1.15.4: resolution: {integrity: sha512-aqqNfs1XTF0HDrFdlY//+SGUxmdSUbjeRXb5iaZc3x0/vMbYmdw9qvOgHWOyyLFxSSRnUuP5+724zBgfw8/WAw==} dependencies: '@types/http-errors': 2.0.3 '@types/mime': 3.0.3 - '@types/node': 20.9.3 + '@types/node': 20.10.4 /@types/sharp@0.31.1: resolution: {integrity: sha512-5nWwamN9ZFHXaYEincMSuza8nNfOof8nmO+mcI+Agx1uMUk4/pQnNIcix+9rLPXzKrm1pS34+6WRDbDV0Jn7ag==} dependencies: - '@types/node': 20.9.3 + '@types/node': 20.10.4 dev: true /@types/stack-utils@2.0.2: @@ -4331,18 +4500,18 @@ packages: /@types/web-push@3.6.3: resolution: {integrity: sha512-v3oT4mMJsHeJ/rraliZ+7TbZtr5bQQuxcgD7C3/1q/zkAj29c8RE0F9lVZVu3hiQe5Z9fYcBreV7TLnfKR+4mg==} dependencies: - '@types/node': 20.9.3 + '@types/node': 20.10.4 dev: true /@types/ws@8.5.8: resolution: {integrity: sha512-flUksGIQCnJd6sZ1l5dqCEG/ksaoAg/eUwiLAGTJQcfgvZJKF++Ta4bJA6A5aPSJmsr+xlseHn4KLgVlNnvPTg==} dependencies: - '@types/node': 20.9.3 + '@types/node': 20.10.4 /@types/xml2js@0.4.14: resolution: {integrity: sha512-4YnrRemBShWRO2QjvUin8ESA41rH+9nQGLUGZV/1IDhi3SL9OhdpNC/MrulTWuptXKwhx/aDxE7toV0f/ypIXQ==} dependencies: - '@types/node': 20.9.3 + '@types/node': 20.10.4 dev: true /@types/yargs-parser@21.0.2: @@ -4361,7 +4530,7 @@ packages: '@types/yargs-parser': 21.0.2 dev: true - /@typescript-eslint/eslint-plugin@6.8.0(@typescript-eslint/parser@6.8.0)(eslint@8.52.0)(typescript@5.3.2): + /@typescript-eslint/eslint-plugin@6.8.0(@typescript-eslint/parser@6.8.0)(eslint@8.52.0)(typescript@5.3.3): resolution: {integrity: sha512-GosF4238Tkes2SHPQ1i8f6rMtG6zlKwMEB0abqSJ3Npvos+doIlc/ATG+vX1G9coDF3Ex78zM3heXHLyWEwLUw==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -4373,10 +4542,10 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.9.1 - '@typescript-eslint/parser': 6.8.0(eslint@8.52.0)(typescript@5.3.2) + '@typescript-eslint/parser': 6.8.0(eslint@8.52.0)(typescript@5.3.3) '@typescript-eslint/scope-manager': 6.8.0 - '@typescript-eslint/type-utils': 6.8.0(eslint@8.52.0)(typescript@5.3.2) - '@typescript-eslint/utils': 6.8.0(eslint@8.52.0)(typescript@5.3.2) + '@typescript-eslint/type-utils': 6.8.0(eslint@8.52.0)(typescript@5.3.3) + '@typescript-eslint/utils': 6.8.0(eslint@8.52.0)(typescript@5.3.3) '@typescript-eslint/visitor-keys': 6.8.0 debug: 4.3.4 eslint: 8.52.0 @@ -4384,13 +4553,13 @@ packages: ignore: 5.2.4 natural-compare: 1.4.0 semver: 7.5.4 - ts-api-utils: 1.0.3(typescript@5.3.2) - typescript: 5.3.2 + ts-api-utils: 1.0.3(typescript@5.3.3) + typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser@6.8.0(eslint@8.52.0)(typescript@5.3.2): + /@typescript-eslint/parser@6.8.0(eslint@8.52.0)(typescript@5.3.3): resolution: {integrity: sha512-5tNs6Bw0j6BdWuP8Fx+VH4G9fEPDxnVI7yH1IAPkQH5RUtvKwRoqdecAPdQXv4rSOADAaz1LFBZvZG7VbXivSg==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -4402,11 +4571,11 @@ packages: dependencies: '@typescript-eslint/scope-manager': 6.8.0 '@typescript-eslint/types': 6.8.0 - '@typescript-eslint/typescript-estree': 6.8.0(typescript@5.3.2) + '@typescript-eslint/typescript-estree': 6.8.0(typescript@5.3.3) '@typescript-eslint/visitor-keys': 6.8.0 debug: 4.3.4 eslint: 8.52.0 - typescript: 5.3.2 + typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true @@ -4427,7 +4596,7 @@ packages: '@typescript-eslint/visitor-keys': 6.8.0 dev: true - /@typescript-eslint/type-utils@6.8.0(eslint@8.52.0)(typescript@5.3.2): + /@typescript-eslint/type-utils@6.8.0(eslint@8.52.0)(typescript@5.3.3): resolution: {integrity: sha512-RYOJdlkTJIXW7GSldUIHqc/Hkto8E+fZN96dMIFhuTJcQwdRoGN2rEWA8U6oXbLo0qufH7NPElUb+MceHtz54g==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -4437,12 +4606,12 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 6.8.0(typescript@5.3.2) - '@typescript-eslint/utils': 6.8.0(eslint@8.52.0)(typescript@5.3.2) + '@typescript-eslint/typescript-estree': 6.8.0(typescript@5.3.3) + '@typescript-eslint/utils': 6.8.0(eslint@8.52.0)(typescript@5.3.3) debug: 4.3.4 eslint: 8.52.0 - ts-api-utils: 1.0.3(typescript@5.3.2) - typescript: 5.3.2 + ts-api-utils: 1.0.3(typescript@5.3.3) + typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true @@ -4457,7 +4626,7 @@ packages: engines: {node: ^16.0.0 || >=18.0.0} dev: true - /@typescript-eslint/typescript-estree@5.62.0(typescript@5.3.2): + /@typescript-eslint/typescript-estree@5.62.0(typescript@5.3.3): resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -4472,13 +4641,13 @@ packages: globby: 11.1.0 is-glob: 4.0.3 semver: 7.5.4 - tsutils: 3.21.0(typescript@5.3.2) - typescript: 5.3.2 + tsutils: 3.21.0(typescript@5.3.3) + typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/typescript-estree@6.8.0(typescript@5.3.2): + /@typescript-eslint/typescript-estree@6.8.0(typescript@5.3.3): resolution: {integrity: sha512-ISgV0lQ8XgW+mvv5My/+iTUdRmGspducmQcDw5JxznasXNnZn3SKNrTRuMsEXv+V/O+Lw9AGcQCfVaOPCAk/Zg==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -4493,13 +4662,13 @@ packages: globby: 11.1.0 is-glob: 4.0.3 semver: 7.5.4 - ts-api-utils: 1.0.3(typescript@5.3.2) - typescript: 5.3.2 + ts-api-utils: 1.0.3(typescript@5.3.3) + typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils@5.62.0(eslint@8.52.0)(typescript@5.3.2): + /@typescript-eslint/utils@5.62.0(eslint@8.52.0)(typescript@5.3.3): resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -4510,7 +4679,7 @@ packages: '@types/semver': 7.5.4 '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.3.2) + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.3.3) eslint: 8.52.0 eslint-scope: 5.1.1 semver: 7.5.4 @@ -4519,7 +4688,7 @@ packages: - typescript dev: true - /@typescript-eslint/utils@6.8.0(eslint@8.52.0)(typescript@5.3.2): + /@typescript-eslint/utils@6.8.0(eslint@8.52.0)(typescript@5.3.3): resolution: {integrity: sha512-dKs1itdE2qFG4jr0dlYLQVppqTE+Itt7GmIf/vX6CSvsW+3ov8PbWauVKyyfNngokhIO9sKZeRGCUo1+N7U98Q==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -4530,7 +4699,7 @@ packages: '@types/semver': 7.5.4 '@typescript-eslint/scope-manager': 6.8.0 '@typescript-eslint/types': 6.8.0 - '@typescript-eslint/typescript-estree': 6.8.0(typescript@5.3.2) + '@typescript-eslint/typescript-estree': 6.8.0(typescript@5.3.3) eslint: 8.52.0 semver: 7.5.4 transitivePeerDependencies: @@ -4777,6 +4946,7 @@ packages: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: acorn: 8.10.0 + dev: true /acorn-walk@8.2.0: resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} @@ -5227,10 +5397,6 @@ packages: dequal: 2.0.3 dev: true - /b4a@1.6.4: - resolution: {integrity: sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==} - dev: false - /babel-jest@29.7.0(@babel/core@7.23.2): resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -5423,6 +5589,7 @@ packages: buffer: 5.7.1 inherits: 2.0.4 readable-stream: 3.6.2 + dev: true /bluebird@3.7.2: resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} @@ -5481,6 +5648,7 @@ packages: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 + dev: true /brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} @@ -5530,6 +5698,7 @@ packages: dependencies: base64-js: 1.5.1 ieee754: 1.2.1 + dev: true /buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} @@ -5659,15 +5828,6 @@ packages: resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} dev: false - /catharsis@0.9.0: - resolution: {integrity: sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==} - engines: {node: '>= 10'} - requiresBuild: true - dependencies: - lodash: 4.17.21 - dev: false - optional: true - /ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} dev: false @@ -5771,10 +5931,6 @@ packages: optionalDependencies: fsevents: 2.3.3 - /chownr@1.1.4: - resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} - dev: false - /chownr@2.0.0: resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} engines: {node: '>=10'} @@ -6057,6 +6213,7 @@ packages: /concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true /conf@9.0.2: resolution: {integrity: sha512-rLSiilO85qHgaTBIIHQpsv8z+NnVfZq3cKuYNCXN1AOqPzced0GWZEe/A517VldRLyQYXUMyV+vszavE2jSAqw==} @@ -6163,8 +6320,8 @@ packages: vary: 1.1.2 dev: false - /cos-nodejs-sdk-v5@2.12.5: - resolution: {integrity: sha512-LziLL0P4CjuaFUN5aingfrZySFaonoN5A5YWjATT+5UXBFbJI6Lz2MPXGOWzR+UBgqZqkQ7aNnd4Fb4krRE/+A==} + /cos-nodejs-sdk-v5@2.12.6: + resolution: {integrity: sha512-Vdnz0s/ATvRp9++YpzER49WWLUtuyVLAjPncGobBK645+tb1pcOCrmJPf2GJSQE+xLkXU3QFN/+LNP6Tm3cXLA==} engines: {node: '>= 6'} dependencies: conf: 9.0.2 @@ -6173,7 +6330,7 @@ packages: request: 2.88.2 dev: false - /cosmiconfig-typescript-loader@4.4.0(@types/node@20.5.1)(cosmiconfig@8.3.6)(ts-node@10.9.1)(typescript@5.3.2): + /cosmiconfig-typescript-loader@4.4.0(@types/node@20.5.1)(cosmiconfig@8.3.6)(ts-node@10.9.2)(typescript@5.3.3): resolution: {integrity: sha512-BabizFdC3wBHhbI4kJh0VkQP9GkBfoHPydD0COMce1nJ1kJAB3F2TmJ/I7diULBKtmEWSwEbuN/KDtgnmUUVmw==} engines: {node: '>=v14.21.3'} peerDependencies: @@ -6183,9 +6340,9 @@ packages: typescript: '>=4' dependencies: '@types/node': 20.5.1 - cosmiconfig: 8.3.6(typescript@5.3.2) - ts-node: 10.9.1(@swc/core@1.3.94)(@types/node@20.5.1)(typescript@5.3.2) - typescript: 5.3.2 + cosmiconfig: 8.3.6(typescript@5.3.3) + ts-node: 10.9.2(@swc/core@1.3.94)(@types/node@20.5.1)(typescript@5.3.3) + typescript: 5.3.3 dev: true /cosmiconfig@8.3.6(typescript@5.2.2): @@ -6204,7 +6361,7 @@ packages: typescript: 5.2.2 dev: true - /cosmiconfig@8.3.6(typescript@5.3.2): + /cosmiconfig@8.3.6(typescript@5.3.3): resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} engines: {node: '>=14'} peerDependencies: @@ -6217,10 +6374,10 @@ packages: js-yaml: 4.1.0 parse-json: 5.2.0 path-type: 4.0.0 - typescript: 5.3.2 + typescript: 5.3.3 dev: true - /create-jest@29.7.0(@types/node@20.9.3)(ts-node@10.9.1): + /create-jest@29.7.0(@types/node@20.10.4)(ts-node@10.9.2): resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -6229,7 +6386,7 @@ packages: chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.9.3)(ts-node@10.9.1) + jest-config: 29.7.0(@types/node@20.10.4)(ts-node@10.9.2) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -6458,6 +6615,7 @@ packages: engines: {node: '>=10'} dependencies: mimic-response: 3.1.0 + dev: true /dedent@1.5.1: resolution: {integrity: sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==} @@ -6468,13 +6626,9 @@ packages: optional: true dev: true - /deep-extend@0.6.0: - resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} - engines: {node: '>=4.0.0'} - dev: false - /deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dev: true /deepmerge@4.3.1: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} @@ -6720,12 +6874,6 @@ packages: dev: false optional: true - /entities@2.1.0: - resolution: {integrity: sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==} - requiresBuild: true - dev: false - optional: true - /entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -6852,6 +7000,7 @@ packages: /escape-string-regexp@2.0.0: resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} engines: {node: '>=8'} + dev: true /escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} @@ -6862,21 +7011,6 @@ packages: resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} engines: {node: '>=12'} - /escodegen@1.14.3: - resolution: {integrity: sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==} - engines: {node: '>=4.0'} - hasBin: true - requiresBuild: true - dependencies: - esprima: 4.0.1 - estraverse: 4.3.0 - esutils: 2.0.3 - optionator: 0.8.3 - optionalDependencies: - source-map: 0.6.1 - dev: false - optional: true - /escodegen@2.1.0: resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} engines: {node: '>=6.0'} @@ -6912,8 +7046,8 @@ packages: eslint: ^7.32.0 || ^8.2.0 eslint-plugin-import: ^2.25.3 dependencies: - '@typescript-eslint/eslint-plugin': 6.8.0(@typescript-eslint/parser@6.8.0)(eslint@8.52.0)(typescript@5.3.2) - '@typescript-eslint/parser': 6.8.0(eslint@8.52.0)(typescript@5.3.2) + '@typescript-eslint/eslint-plugin': 6.8.0(@typescript-eslint/parser@6.8.0)(eslint@8.52.0)(typescript@5.3.3) + '@typescript-eslint/parser': 6.8.0(eslint@8.52.0)(typescript@5.3.3) eslint: 8.52.0 eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.28.1)(eslint@8.52.0) eslint-plugin-import: 2.28.1(@typescript-eslint/parser@6.8.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.52.0) @@ -7002,7 +7136,7 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 6.8.0(eslint@8.52.0)(typescript@5.3.2) + '@typescript-eslint/parser': 6.8.0(eslint@8.52.0)(typescript@5.3.3) debug: 3.2.7 eslint: 8.52.0 eslint-import-resolver-node: 0.3.9 @@ -7032,7 +7166,7 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 6.8.0(eslint@8.52.0)(typescript@5.3.2) + '@typescript-eslint/parser': 6.8.0(eslint@8.52.0)(typescript@5.3.3) array-includes: 3.1.7 array.prototype.findlastindex: 1.2.3 array.prototype.flat: 1.3.2 @@ -7057,7 +7191,7 @@ packages: - supports-color dev: true - /eslint-plugin-jest@27.4.3(@typescript-eslint/eslint-plugin@6.8.0)(eslint@8.52.0)(jest@29.7.0)(typescript@5.3.2): + /eslint-plugin-jest@27.4.3(@typescript-eslint/eslint-plugin@6.8.0)(eslint@8.52.0)(jest@29.7.0)(typescript@5.3.3): resolution: {integrity: sha512-7S6SmmsHsgIm06BAGCAxL+ABd9/IB3MWkz2pudj6Qqor2y1qQpWPfuFU4SG9pWj4xDjF0e+D7Llh5useuSzAZw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -7070,10 +7204,10 @@ packages: jest: optional: true dependencies: - '@typescript-eslint/eslint-plugin': 6.8.0(@typescript-eslint/parser@6.8.0)(eslint@8.52.0)(typescript@5.3.2) - '@typescript-eslint/utils': 5.62.0(eslint@8.52.0)(typescript@5.3.2) + '@typescript-eslint/eslint-plugin': 6.8.0(@typescript-eslint/parser@6.8.0)(eslint@8.52.0)(typescript@5.3.3) + '@typescript-eslint/utils': 5.62.0(eslint@8.52.0)(typescript@5.3.3) eslint: 8.52.0 - jest: 29.7.0(@types/node@20.9.3)(ts-node@10.9.1) + jest: 29.7.0(@types/node@20.10.4)(ts-node@10.9.2) transitivePeerDependencies: - supports-color - typescript @@ -7181,6 +7315,7 @@ packages: /eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true /eslint@8.52.0: resolution: {integrity: sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg==} @@ -7236,6 +7371,7 @@ packages: acorn: 8.10.0 acorn-jsx: 5.3.2(acorn@8.10.0) eslint-visitor-keys: 3.4.3 + dev: true /esprima@4.0.1: resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} @@ -7259,14 +7395,17 @@ packages: /estraverse@4.3.0: resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} engines: {node: '>=4.0'} + dev: true /estraverse@5.3.0: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} + dev: true /esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + dev: true /etag@1.8.1: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} @@ -7369,11 +7508,6 @@ packages: engines: {node: '>= 0.8.0'} dev: true - /expand-template@2.0.3: - resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} - engines: {node: '>=6'} - dev: false - /expect@29.7.0: resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -7480,10 +7614,6 @@ packages: resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} dev: true - /fast-fifo@1.3.2: - resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} - dev: false - /fast-glob@3.3.1: resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} engines: {node: '>=8.6.0'} @@ -7522,6 +7652,7 @@ packages: /fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + dev: true /fast-querystring@1.1.2: resolution: {integrity: sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==} @@ -7536,12 +7667,6 @@ packages: /fast-safe-stringify@2.1.1: resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} - /fast-text-encoding@1.0.6: - resolution: {integrity: sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w==} - requiresBuild: true - dev: false - optional: true - /fast-uri@2.2.0: resolution: {integrity: sha512-cIusKBIt/R/oI6z/1nyfe2FvGKVTohVRfvkOhvx0nCEW+xf5NoCXjAHcWp93uOUBchzYcsvPlrapAdX1uW+YGg==} dev: false @@ -7761,21 +7886,21 @@ packages: semver-regex: 4.0.5 dev: true - /firebase-admin@11.11.0: - resolution: {integrity: sha512-lp784gXFAJgUEtjSdYNZGTWZqltqjBkoaPSQhDKnmWXJP/MCbWdiDY1hsdkl/6O4O4KFovTjUDLu26sojwdQvw==} + /firebase-admin@12.0.0: + resolution: {integrity: sha512-wBrrSSsKV++/+O8E7O/C7/wL0nbG/x4Xv4yatz/+sohaZ+LsnWtYUcrd3gZutO86hLpDex7xgyrkKbgulmtVyQ==} engines: {node: '>=14'} dependencies: '@fastify/busboy': 1.2.1 - '@firebase/database-compat': 0.3.4 - '@firebase/database-types': 0.10.4 - '@types/node': 20.9.3 + '@firebase/database-compat': 1.0.2 + '@firebase/database-types': 1.0.0 + '@types/node': 20.10.4 jsonwebtoken: 9.0.2 jwks-rsa: 3.1.0 node-forge: 1.3.1 uuid: 9.0.1 optionalDependencies: - '@google-cloud/firestore': 6.8.0 - '@google-cloud/storage': 6.12.0 + '@google-cloud/firestore': 7.1.0 + '@google-cloud/storage': 7.7.0 transitivePeerDependencies: - encoding - supports-color @@ -7893,10 +8018,6 @@ packages: engines: {node: '>= 0.6'} dev: false - /fs-constants@1.0.0: - resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} - dev: false - /fs-extra@10.1.0: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} engines: {node: '>=12'} @@ -7906,8 +8027,8 @@ packages: universalify: 2.0.0 dev: true - /fs-extra@11.1.1: - resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==} + /fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} engines: {node: '>=14.14'} dependencies: graceful-fs: 4.2.11 @@ -7963,13 +8084,13 @@ packages: /functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - /gaxios@5.1.3: - resolution: {integrity: sha512-95hVgBRgEIRQQQHIbnxBXeHbW4TqFk4ZDJW7wmVtvYar72FdhRIo1UGOLS2eRAKCPEdPBWu+M7+A33D9CdX9rA==} - engines: {node: '>=12'} + /gaxios@6.1.1: + resolution: {integrity: sha512-bw8smrX+XlAoo9o1JAksBwX+hi/RG15J+NTSxmNPIclKC3ZVK6C2afwY8OSdRvOK0+ZLecUJYtj2MmjOt3Dm0w==} + engines: {node: '>=14'} requiresBuild: true dependencies: extend: 3.0.2 - https-proxy-agent: 5.0.1 + https-proxy-agent: 7.0.2 is-stream: 2.0.1 node-fetch: 2.6.13 transitivePeerDependencies: @@ -7978,12 +8099,12 @@ packages: dev: false optional: true - /gcp-metadata@5.3.0: - resolution: {integrity: sha512-FNTkdNEnBdlqF2oatizolQqNANMrcqJt6AAYt99B3y1aLLC8Hc5IOBb+ZnnzllodEEf6xMBp6wRcBbc16fa65w==} - engines: {node: '>=12'} + /gcp-metadata@6.1.0: + resolution: {integrity: sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==} + engines: {node: '>=14'} requiresBuild: true dependencies: - gaxios: 5.1.3 + gaxios: 6.1.1 json-bigint: 1.0.0 transitivePeerDependencies: - encoding @@ -8060,10 +8181,6 @@ packages: through2: 4.0.2 dev: true - /github-from-package@0.0.0: - resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} - dev: false - /glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -8102,6 +8219,7 @@ packages: minimatch: 3.1.2 once: 1.4.0 path-is-absolute: 1.0.1 + dev: true /glob@8.1.0: resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} @@ -8181,63 +8299,45 @@ packages: resolution: {integrity: sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==} dev: true - /google-auth-library@8.9.0: - resolution: {integrity: sha512-f7aQCJODJFmYWN6PeNKzgvy9LI2tYmXnzpNDHEjG5sDNPgGb2FXQyTBnXeSH+PAtpKESFD+LmHw3Ox3mN7e1Fg==} - engines: {node: '>=12'} + /google-auth-library@9.4.1: + resolution: {integrity: sha512-Chs7cuzDuav8W/BXOoRgSXw4u0zxYtuqAHETDR5Q6dG1RwNwz7NUKjsDDHAsBV3KkiiJBtJqjbzy1XU1L41w1g==} + engines: {node: '>=14'} requiresBuild: true dependencies: - arrify: 2.0.1 base64-js: 1.5.1 ecdsa-sig-formatter: 1.0.11 - fast-text-encoding: 1.0.6 - gaxios: 5.1.3 - gcp-metadata: 5.3.0 - gtoken: 6.1.2 + gaxios: 6.1.1 + gcp-metadata: 6.1.0 + gtoken: 7.0.1 jws: 4.0.0 - lru-cache: 6.0.0 transitivePeerDependencies: - encoding - supports-color dev: false optional: true - /google-gax@3.6.1: - resolution: {integrity: sha512-g/lcUjGcB6DSw2HxgEmCDOrI/CByOwqRvsuUvNalHUK2iPPPlmAIpbMbl62u0YufGMr8zgE3JL7th6dCb1Ry+w==} - engines: {node: '>=12'} - hasBin: true + /google-gax@4.0.5: + resolution: {integrity: sha512-yLoYtp4zE+8OQA74oBEbNkbzI6c95W01JSL7RqC8XERKpRvj3ytZp1dgnbA6G9aRsc8pZB25xWYBcCmrbYOEhA==} + engines: {node: '>=14'} requiresBuild: true dependencies: - '@grpc/grpc-js': 1.8.21 + '@grpc/grpc-js': 1.9.12 '@grpc/proto-loader': 0.7.10 '@types/long': 4.0.2 - '@types/rimraf': 3.0.2 abort-controller: 3.0.0 duplexify: 4.1.2 - fast-text-encoding: 1.0.6 - google-auth-library: 8.9.0 - is-stream-ended: 0.1.4 + google-auth-library: 9.4.1 node-fetch: 2.6.13 object-hash: 3.0.0 - proto3-json-serializer: 1.1.1 - protobufjs: 7.2.4 - protobufjs-cli: 1.1.1(protobufjs@7.2.4) - retry-request: 5.0.2 + proto3-json-serializer: 2.0.0 + protobufjs: 7.2.5 + retry-request: 7.0.1 transitivePeerDependencies: - encoding - supports-color dev: false optional: true - /google-p12-pem@4.0.1: - resolution: {integrity: sha512-WPkN4yGtz05WZ5EhtlxNDWPhC4JIic6G8ePitwUWy4l+XPVYec+a0j0Ts47PDtW59y3RwAhUd9/h9ZZ63px6RQ==} - engines: {node: '>=12.0.0'} - hasBin: true - requiresBuild: true - dependencies: - node-forge: 1.3.1 - dev: false - optional: true - /gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: @@ -8267,7 +8367,7 @@ packages: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} dev: true - /graphql-config@5.0.3(@types/node@20.9.3)(graphql@16.8.1)(typescript@5.3.2): + /graphql-config@5.0.3(@types/node@20.10.4)(graphql@16.8.1)(typescript@5.3.3): resolution: {integrity: sha512-BNGZaoxIBkv9yy6Y7omvsaBUHOzfFcII3UN++tpH8MGOKFPFkCPZuwx09ggANMt8FgyWP1Od8SWPmrUEZca4NQ==} engines: {node: '>= 16.0.0'} peerDependencies: @@ -8281,9 +8381,9 @@ packages: '@graphql-tools/json-file-loader': 8.0.0(graphql@16.8.1) '@graphql-tools/load': 8.0.0(graphql@16.8.1) '@graphql-tools/merge': 9.0.0(graphql@16.8.1) - '@graphql-tools/url-loader': 8.0.0(@types/node@20.9.3)(graphql@16.8.1) + '@graphql-tools/url-loader': 8.0.0(@types/node@20.10.4)(graphql@16.8.1) '@graphql-tools/utils': 10.0.7(graphql@16.8.1) - cosmiconfig: 8.3.6(typescript@5.3.2) + cosmiconfig: 8.3.6(typescript@5.3.3) graphql: 16.8.1 jiti: 1.20.0 minimatch: 4.2.3 @@ -8339,13 +8439,12 @@ packages: resolution: {integrity: sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==} engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} - /gtoken@6.1.2: - resolution: {integrity: sha512-4ccGpzz7YAr7lxrT2neugmXQ3hP9ho2gcaityLVkiUecAiwiy60Ii8gRbZeOsXV19fYaRjgBSshs8kXw+NKCPQ==} - engines: {node: '>=12.0.0'} + /gtoken@7.0.1: + resolution: {integrity: sha512-KcFVtoP1CVFtQu0aSk3AyAt2og66PFhZAlkUOuWKwzMLoulHXG5W5wE5xAnHb+yl3/wEFoqGW7/cDGMU8igDZQ==} + engines: {node: '>=14.0.0'} requiresBuild: true dependencies: - gaxios: 5.1.3 - google-p12-pem: 4.0.1 + gaxios: 6.1.1 jws: 4.0.0 transitivePeerDependencies: - encoding @@ -8878,6 +8977,7 @@ packages: /ini@1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + dev: true /inquirer@8.2.4: resolution: {integrity: sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==} @@ -8941,7 +9041,7 @@ packages: json-bigint: 1.0.0 lodash: 4.17.21 luxon: 1.28.1 - reflect-metadata: 0.1.13 + reflect-metadata: 0.1.14 request: 2.88.2 request-promise: 4.2.6(request@2.88.2) rxjs: 6.6.7 @@ -9209,12 +9309,6 @@ packages: dependencies: call-bind: 1.0.5 - /is-stream-ended@0.1.4: - resolution: {integrity: sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw==} - requiresBuild: true - dev: false - optional: true - /is-stream@1.1.0: resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==} engines: {node: '>=0.10.0'} @@ -9435,7 +9529,7 @@ packages: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.9.3 + '@types/node': 20.10.4 chalk: 4.1.2 co: 4.6.0 dedent: 1.5.1 @@ -9456,7 +9550,7 @@ packages: - supports-color dev: true - /jest-cli@29.7.0(@types/node@20.9.3)(ts-node@10.9.1): + /jest-cli@29.7.0(@types/node@20.10.4)(ts-node@10.9.2): resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -9466,14 +9560,14 @@ packages: node-notifier: optional: true dependencies: - '@jest/core': 29.7.0(ts-node@10.9.1) + '@jest/core': 29.7.0(ts-node@10.9.2) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.9.3)(ts-node@10.9.1) + create-jest: 29.7.0(@types/node@20.10.4)(ts-node@10.9.2) exit: 0.1.2 import-local: 3.1.0 - jest-config: 29.7.0(@types/node@20.9.3)(ts-node@10.9.1) + jest-config: 29.7.0(@types/node@20.10.4)(ts-node@10.9.2) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -9484,7 +9578,7 @@ packages: - ts-node dev: true - /jest-config@29.7.0(@types/node@20.9.3)(ts-node@10.9.1): + /jest-config@29.7.0(@types/node@20.10.4)(ts-node@10.9.2): resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -9499,7 +9593,7 @@ packages: '@babel/core': 7.23.2 '@jest/test-sequencer': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.9.3 + '@types/node': 20.10.4 babel-jest: 29.7.0(@babel/core@7.23.2) chalk: 4.1.2 ci-info: 3.9.0 @@ -9519,7 +9613,7 @@ packages: pretty-format: 29.7.0 slash: 3.0.0 strip-json-comments: 3.1.1 - ts-node: 10.9.1(@swc/core@1.3.94)(@types/node@20.9.3)(typescript@5.3.2) + ts-node: 10.9.2(@swc/core@1.3.94)(@types/node@20.10.4)(typescript@5.3.3) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -9566,7 +9660,7 @@ packages: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 '@types/jsdom': 20.0.1 - '@types/node': 20.9.3 + '@types/node': 20.10.4 jest-mock: 29.7.0 jest-util: 29.7.0 jsdom: 20.0.3 @@ -9583,7 +9677,7 @@ packages: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.9.3 + '@types/node': 20.10.4 jest-mock: 29.7.0 jest-util: 29.7.0 dev: true @@ -9599,7 +9693,7 @@ packages: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.8 - '@types/node': 20.9.3 + '@types/node': 20.10.4 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -9650,7 +9744,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.9.3 + '@types/node': 20.10.4 jest-util: 29.7.0 dev: true @@ -9705,7 +9799,7 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.9.3 + '@types/node': 20.10.4 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -9736,7 +9830,7 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.9.3 + '@types/node': 20.10.4 chalk: 4.1.2 cjs-module-lexer: 1.2.3 collect-v8-coverage: 1.0.2 @@ -9788,7 +9882,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.9.3 + '@types/node': 20.10.4 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -9813,7 +9907,7 @@ packages: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.9.3 + '@types/node': 20.10.4 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -9825,7 +9919,7 @@ packages: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 20.9.3 + '@types/node': 20.10.4 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true @@ -9834,13 +9928,13 @@ packages: resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@types/node': 20.9.3 + '@types/node': 20.10.4 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true - /jest@29.7.0(@types/node@20.9.3)(ts-node@10.9.1): + /jest@29.7.0(@types/node@20.10.4)(ts-node@10.9.2): resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -9850,10 +9944,10 @@ packages: node-notifier: optional: true dependencies: - '@jest/core': 29.7.0(ts-node@10.9.1) + '@jest/core': 29.7.0(ts-node@10.9.2) '@jest/types': 29.6.3 import-local: 3.1.0 - jest-cli: 29.7.0(@types/node@20.9.3)(ts-node@10.9.1) + jest-cli: 29.7.0(@types/node@20.10.4)(ts-node@10.9.2) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -9886,42 +9980,10 @@ packages: dependencies: argparse: 2.0.1 - /js2xmlparser@4.0.2: - resolution: {integrity: sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==} - requiresBuild: true - dependencies: - xmlcreate: 2.0.4 - dev: false - optional: true - /jsbn@0.1.1: resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} dev: false - /jsdoc@4.0.2: - resolution: {integrity: sha512-e8cIg2z62InH7azBBi3EsSEqrKx+nUtAS5bBcYTSpZFA+vhNPyhv8PTFZ0WsjOPDj04/dOLlm08EDcQJDqaGQg==} - engines: {node: '>=12.0.0'} - hasBin: true - requiresBuild: true - dependencies: - '@babel/parser': 7.23.0 - '@jsdoc/salty': 0.2.5 - '@types/markdown-it': 12.2.3 - bluebird: 3.7.2 - catharsis: 0.9.0 - escape-string-regexp: 2.0.0 - js2xmlparser: 4.0.2 - klaw: 3.0.0 - markdown-it: 12.3.2 - markdown-it-anchor: 8.6.7(@types/markdown-it@12.2.3)(markdown-it@12.3.2) - marked: 4.3.0 - mkdirp: 1.0.4 - requizzle: 0.2.4 - strip-json-comments: 3.1.1 - underscore: 1.13.6 - dev: false - optional: true - /jsdom@20.0.3: resolution: {integrity: sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==} engines: {node: '>=14'} @@ -10145,7 +10207,7 @@ packages: engines: {node: '>=14'} dependencies: '@types/express': 4.17.20 - '@types/jsonwebtoken': 9.0.4 + '@types/jsonwebtoken': 9.0.5 debug: 4.3.4 jose: 4.15.4 limiter: 1.1.5 @@ -10179,14 +10241,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /klaw@3.0.0: - resolution: {integrity: sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==} - requiresBuild: true - dependencies: - graceful-fs: 4.2.11 - dev: false - optional: true - /kleur@3.0.3: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} engines: {node: '>=6'} @@ -10224,16 +10278,6 @@ packages: engines: {node: '>=6'} dev: true - /levn@0.3.0: - resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} - engines: {node: '>= 0.8.0'} - requiresBuild: true - dependencies: - prelude-ls: 1.1.2 - type-check: 0.3.2 - dev: false - optional: true - /levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -10266,14 +10310,6 @@ packages: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} dev: true - /linkify-it@3.0.3: - resolution: {integrity: sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==} - requiresBuild: true - dependencies: - uc.micro: 1.0.6 - dev: false - optional: true - /lint-staged@13.3.0: resolution: {integrity: sha512-mPRtrYnipYYv1FEE134ufbWpeggNTo+O/UPzngoaKzbzHAthvR55am+8GfHTnqNRQVRRrYQLGW9ZyUoD7DsBHQ==} engines: {node: ^16.14.0 || >=18.0.0} @@ -10658,43 +10694,10 @@ packages: resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} engines: {node: '>=8'} - /markdown-it-anchor@8.6.7(@types/markdown-it@12.2.3)(markdown-it@12.3.2): - resolution: {integrity: sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==} - requiresBuild: true - peerDependencies: - '@types/markdown-it': '*' - markdown-it: '*' - dependencies: - '@types/markdown-it': 12.2.3 - markdown-it: 12.3.2 - dev: false - optional: true - - /markdown-it@12.3.2: - resolution: {integrity: sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==} - hasBin: true - requiresBuild: true - dependencies: - argparse: 2.0.1 - entities: 2.1.0 - linkify-it: 3.0.3 - mdurl: 1.0.1 - uc.micro: 1.0.6 - dev: false - optional: true - /markdown-table@3.0.3: resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==} dev: false - /marked@4.3.0: - resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==} - engines: {node: '>= 12'} - hasBin: true - requiresBuild: true - dev: false - optional: true - /mathml-tag-names@2.1.3: resolution: {integrity: sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==} dev: true @@ -10847,12 +10850,6 @@ packages: resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} dev: true - /mdurl@1.0.1: - resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} - requiresBuild: true - dev: false - optional: true - /media-typer@0.3.0: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} @@ -10917,7 +10914,7 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - /meros@1.3.0(@types/node@20.9.3): + /meros@1.3.0(@types/node@20.10.4): resolution: {integrity: sha512-2BNGOimxEz5hmjUG2FwoxCt5HN7BXdaWyFqEwxPTrJzVdABtrL4TiHTcsWSFAxPQ/tOnEaQEJh3qWq71QRMY+w==} engines: {node: '>=13'} peerDependencies: @@ -10926,7 +10923,7 @@ packages: '@types/node': optional: true dependencies: - '@types/node': 20.9.3 + '@types/node': 20.10.4 dev: true /methods@1.1.2: @@ -11259,6 +11256,7 @@ packages: /mimic-response@3.1.0: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} + dev: true /min-indent@1.0.1: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} @@ -11273,6 +11271,7 @@ packages: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: brace-expansion: 1.1.11 + dev: true /minimatch@4.2.3: resolution: {integrity: sha512-lIUdtK5hdofgCTu3aT0sOaHsYR37viUuIc0rwnnDXImbwFRcumyLMeZaM0t0I/fgxS6s6JMfu0rLD1Wz9pv1ng==} @@ -11383,14 +11382,11 @@ packages: yallist: 4.0.0 dev: true - /mkdirp-classic@0.5.3: - resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} - dev: false - /mkdirp@1.0.4: resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} engines: {node: '>=10'} hasBin: true + dev: true /mkdirp@2.1.6: resolution: {integrity: sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==} @@ -11442,10 +11438,6 @@ packages: hasBin: true dev: true - /napi-build-utils@1.0.2: - resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==} - dev: false - /natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} dev: true @@ -11479,13 +11471,6 @@ packages: tslib: 2.6.2 dev: true - /node-abi@3.51.0: - resolution: {integrity: sha512-SQkEP4hmNWjlniS5zdnfIXTk1x7Ome85RDzHlTbBtzE97Gfwz/Ipw4v/Ryk20DWIy3yCNVLVlGKApCnmvYoJbA==} - engines: {node: '>=10'} - dependencies: - semver: 7.5.4 - dev: false - /node-abort-controller@3.1.1: resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==} @@ -11495,10 +11480,6 @@ packages: dev: false optional: true - /node-addon-api@6.1.0: - resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==} - dev: false - /node-addon-api@7.0.0: resolution: {integrity: sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA==} dev: true @@ -11871,20 +11852,6 @@ packages: hasBin: true dev: false - /optionator@0.8.3: - resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} - engines: {node: '>= 0.8.0'} - requiresBuild: true - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.3.0 - prelude-ls: 1.1.2 - type-check: 0.3.2 - word-wrap: 1.2.5 - dev: false - optional: true - /optionator@0.9.3: resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} engines: {node: '>= 0.8.0'} @@ -12103,8 +12070,8 @@ packages: engines: {node: '>= 0.4.0'} dev: false - /passport@0.6.0: - resolution: {integrity: sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug==} + /passport@0.7.0: + resolution: {integrity: sha512-cPLl+qZpSc+ireUvt+IzqbED1cHHkDoVYMo30jbJIdOOjQ1MQYZBPiNvmi8UM6lJuOpTPXJGZQk0DtC4y61MYQ==} engines: {node: '>= 0.4.0'} dependencies: passport-strategy: 1.0.0 @@ -12132,6 +12099,7 @@ packages: /path-is-absolute@1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} + dev: true /path-key@2.0.1: resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} @@ -12204,8 +12172,8 @@ packages: engines: {node: '>=14.16'} dev: true - /peer@1.0.1: - resolution: {integrity: sha512-L0aa9psC0RyMWD5nc30DJnmDnq3wKbB23u6bghG3kfrj1cIXtgihwukvIzJW5Qhw2OJI0baLWYYr8HE7hIAfIg==} + /peer@1.0.2: + resolution: {integrity: sha512-ZObVEhAaoskd3KuSxr5DJLM8QuqQW4w3i0MqrI8H7Bzz8DjRC3DjUg2XtQQGfdc36+8Xk+wIPT/tL5wE+KnIqg==} engines: {node: '>=14'} hasBin: true dependencies: @@ -12466,32 +12434,6 @@ packages: xtend: 4.0.2 dev: false - /prebuild-install@7.1.1: - resolution: {integrity: sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==} - engines: {node: '>=10'} - hasBin: true - dependencies: - detect-libc: 2.0.2 - expand-template: 2.0.3 - github-from-package: 0.0.0 - minimist: 1.2.8 - mkdirp-classic: 0.5.3 - napi-build-utils: 1.0.2 - node-abi: 3.51.0 - pump: 3.0.0 - rc: 1.2.8 - simple-get: 4.0.1 - tar-fs: 2.1.1 - tunnel-agent: 0.6.0 - dev: false - - /prelude-ls@1.1.2: - resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} - engines: {node: '>= 0.8.0'} - requiresBuild: true - dev: false - optional: true - /prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -12574,13 +12516,13 @@ packages: react-is: 18.2.0 dev: true - /prisma@5.6.0: - resolution: {integrity: sha512-EEaccku4ZGshdr2cthYHhf7iyvCcXqwJDvnoQRAJg5ge2Tzpv0e2BaMCp+CbbDUwoVTzwgOap9Zp+d4jFa2O9A==} + /prisma@5.7.0: + resolution: {integrity: sha512-0rcfXO2ErmGAtxnuTNHQT9ztL0zZheQjOI/VNJzdq87C3TlGPQtMqtM+KCwU6XtmkoEr7vbCQqA7HF9IY0ST+Q==} engines: {node: '>=16.13'} hasBin: true requiresBuild: true dependencies: - '@prisma/engines': 5.6.0 + '@prisma/engines': 5.7.0 /proc-log@3.0.0: resolution: {integrity: sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==} @@ -12637,57 +12579,15 @@ packages: resolution: {integrity: sha512-gVNZ74nqhRMiIUYWGQdosYetaKc83x8oT41a0LlV3AAFCAZwCpg4vmGkq8t34+cUhp3cnM4XDiU/7xlgK7HGrg==} dev: false - /proto3-json-serializer@1.1.1: - resolution: {integrity: sha512-AwAuY4g9nxx0u52DnSMkqqgyLHaW/XaPLtaAo3y/ZCfeaQB/g4YDH4kb8Wc/mWzWvu0YjOznVnfn373MVZZrgw==} - engines: {node: '>=12.0.0'} + /proto3-json-serializer@2.0.0: + resolution: {integrity: sha512-FB/YaNrpiPkyQNSNPilpn8qn0KdEfkgmJ9JP93PQyF/U4bAiXY5BiUdDhiDO4S48uSQ6AesklgVlrKiqZPzegw==} + engines: {node: '>=14.0.0'} requiresBuild: true dependencies: protobufjs: 7.2.5 dev: false optional: true - /protobufjs-cli@1.1.1(protobufjs@7.2.4): - resolution: {integrity: sha512-VPWMgIcRNyQwWUv8OLPyGQ/0lQY/QTQAVN5fh+XzfDwsVw1FZ2L3DM/bcBf8WPiRz2tNpaov9lPZfNcmNo6LXA==} - engines: {node: '>=12.0.0'} - hasBin: true - requiresBuild: true - peerDependencies: - protobufjs: ^7.0.0 - dependencies: - chalk: 4.1.2 - escodegen: 1.14.3 - espree: 9.6.1 - estraverse: 5.3.0 - glob: 8.1.0 - jsdoc: 4.0.2 - minimist: 1.2.8 - protobufjs: 7.2.4 - semver: 7.5.4 - tmp: 0.2.1 - uglify-js: 3.17.4 - dev: false - optional: true - - /protobufjs@7.2.4: - resolution: {integrity: sha512-AT+RJgD2sH8phPmCf7OUZR8xGdcJRga4+1cOaXJ64hvcSkVhNcRHOwIxUatPH15+nj59WAGTDv3LSGZPEQbJaQ==} - engines: {node: '>=12.0.0'} - requiresBuild: true - dependencies: - '@protobufjs/aspromise': 1.1.2 - '@protobufjs/base64': 1.1.2 - '@protobufjs/codegen': 2.0.4 - '@protobufjs/eventemitter': 1.1.0 - '@protobufjs/fetch': 1.1.0 - '@protobufjs/float': 1.0.2 - '@protobufjs/inquire': 1.1.0 - '@protobufjs/path': 1.1.2 - '@protobufjs/pool': 1.1.0 - '@protobufjs/utf8': 1.1.0 - '@types/node': 20.9.3 - long: 5.2.3 - dev: false - optional: true - /protobufjs@7.2.5: resolution: {integrity: sha512-gGXRSXvxQ7UiPgfw8gevrfRWcTlSbOFg+p/N+JVJEK5VhueL2miT6qTymqAmjr1Q5WbOCyJbyrk6JfWKwlFn6A==} engines: {node: '>=12.0.0'} @@ -12703,7 +12603,7 @@ packages: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 20.9.3 + '@types/node': 20.10.4 long: 5.2.3 dev: false optional: true @@ -12734,6 +12634,7 @@ packages: dependencies: end-of-stream: 1.4.4 once: 1.4.0 + dev: true /punycode@1.4.1: resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} @@ -12758,8 +12659,8 @@ packages: engines: {node: '>=6.0.0'} dev: true - /qqwry.ipdb@2023.11.15: - resolution: {integrity: sha512-r0fttwSFr/nRi5Lra9Cv7nVdZiR2A9OBxK51U11np7sMt/am2wQDQ7bFVXg8O1KHPeq+Yqei1zszf1TiBwKVig==} + /qqwry.ipdb@2023.11.22: + resolution: {integrity: sha512-Z8vZmx8ApVUvxP/kF9xkIzMT2X/qkN2+W3a6+8x9eRipNgoHjWxdGcv1ZzHTmtc2UlYCWZp72HXiVKSNiL2T3g==} dev: false /qs@6.10.4: @@ -12799,10 +12700,6 @@ packages: /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - /queue-tick@1.0.1: - resolution: {integrity: sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==} - dev: false - /quick-format-unescaped@4.0.4: resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} dev: false @@ -12848,16 +12745,6 @@ packages: unpipe: 1.0.0 dev: false - /rc@1.2.8: - resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} - hasBin: true - dependencies: - deep-extend: 0.6.0 - ini: 1.3.8 - minimist: 1.2.8 - strip-json-comments: 2.0.1 - dev: false - /react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} dev: true @@ -13005,6 +12892,10 @@ packages: /reflect-metadata@0.1.13: resolution: {integrity: sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==} + dev: false + + /reflect-metadata@0.1.14: + resolution: {integrity: sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==} /reflect.getprototypeof@1.0.4: resolution: {integrity: sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw==} @@ -13218,14 +13109,6 @@ packages: /requires-port@1.0.0: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} - /requizzle@0.2.4: - resolution: {integrity: sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==} - requiresBuild: true - dependencies: - lodash: 4.17.21 - dev: false - optional: true - /resolve-alpn@1.2.1: resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} dev: true @@ -13308,14 +13191,17 @@ packages: engines: {node: '>=4'} dev: false - /retry-request@5.0.2: - resolution: {integrity: sha512-wfI3pk7EE80lCIXprqh7ym48IHYdwmAAzESdbU8Q9l7pnRCk9LEhpbOTNKjz6FARLm/Bl5m+4F0ABxOkYUujSQ==} - engines: {node: '>=12'} + /retry-request@7.0.1: + resolution: {integrity: sha512-ZI6vJp9rfB71mrZpw+n9p/B6HCsd7QJlSEQftZ+xfJzr3cQ9EPGKw1FF0BnViJ0fYREX6FhymBD2CARpmsFciQ==} + engines: {node: '>=14'} requiresBuild: true dependencies: + '@types/request': 2.48.11 debug: 4.3.4 extend: 3.0.2 + teeny-request: 9.0.0 transitivePeerDependencies: + - encoding - supports-color dev: false optional: true @@ -13342,6 +13228,7 @@ packages: hasBin: true dependencies: glob: 7.2.3 + dev: true /rimraf@4.4.1: resolution: {integrity: sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==} @@ -13577,19 +13464,34 @@ packages: safe-buffer: 5.2.1 dev: false - /sharp@0.32.6: - resolution: {integrity: sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==} - engines: {node: '>=14.15.0'} + /sharp@0.33.0: + resolution: {integrity: sha512-99DZKudjm/Rmz+M0/26t4DKpXyywAOJaayGS9boEn7FvgtG0RYBi46uPE2c+obcJRtA3AZa0QwJot63gJQ1F0Q==} + engines: {libvips: '>=8.15.0', node: ^18.17.0 || ^20.3.0 || >=21.0.0} requiresBuild: true dependencies: color: 4.2.3 detect-libc: 2.0.2 - node-addon-api: 6.1.0 - prebuild-install: 7.1.1 semver: 7.5.4 - simple-get: 4.0.1 - tar-fs: 3.0.4 - tunnel-agent: 0.6.0 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.33.0 + '@img/sharp-darwin-x64': 0.33.0 + '@img/sharp-libvips-darwin-arm64': 1.0.0 + '@img/sharp-libvips-darwin-x64': 1.0.0 + '@img/sharp-libvips-linux-arm': 1.0.0 + '@img/sharp-libvips-linux-arm64': 1.0.0 + '@img/sharp-libvips-linux-s390x': 1.0.0 + '@img/sharp-libvips-linux-x64': 1.0.0 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.0 + '@img/sharp-libvips-linuxmusl-x64': 1.0.0 + '@img/sharp-linux-arm': 0.33.0 + '@img/sharp-linux-arm64': 0.33.0 + '@img/sharp-linux-s390x': 0.33.0 + '@img/sharp-linux-x64': 0.33.0 + '@img/sharp-linuxmusl-arm64': 0.33.0 + '@img/sharp-linuxmusl-x64': 0.33.0 + '@img/sharp-wasm32': 0.33.0 + '@img/sharp-win32-ia32': 0.33.0 + '@img/sharp-win32-x64': 0.33.0 dev: false /shebang-command@1.2.0: @@ -13692,18 +13594,6 @@ packages: resolution: {integrity: sha512-6+eerH9fEnNmi/hyM1DXcRK3pWdoMQtlkQ+ns0ntzunjKqp5i3sKCc80ym8Fib3iaYhdJUOPdhlJWj1tvge2Ww==} dev: true - /simple-concat@1.0.1: - resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} - dev: false - - /simple-get@4.0.1: - resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} - dependencies: - decompress-response: 6.0.0 - once: 1.4.0 - simple-concat: 1.0.1 - dev: false - /simple-swizzle@0.2.2: resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} dependencies: @@ -13949,13 +13839,6 @@ packages: engines: {node: '>=10.0.0'} dev: true - /streamx@2.15.1: - resolution: {integrity: sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==} - dependencies: - fast-fifo: 1.3.2 - queue-tick: 1.0.1 - dev: false - /string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} @@ -14109,14 +13992,10 @@ packages: min-indent: 1.0.1 dev: true - /strip-json-comments@2.0.1: - resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} - engines: {node: '>=0.10.0'} - dev: false - /strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + dev: true /strip-outer@2.0.0: resolution: {integrity: sha512-A21Xsm1XzUkK0qK1ZrytDUvqsQWict2Cykhvi0fBQntGG5JSprESasEyV1EZ/4CiR5WB5KjzLTrP/bO37B0wPg==} @@ -14150,7 +14029,7 @@ packages: peerDependencies: stylelint: ^14.5.1 || ^15.0.0 dependencies: - stylelint: 15.11.0(typescript@5.3.2) + stylelint: 15.11.0(typescript@5.3.3) optionalDependencies: stylelint-scss: 5.2.1(stylelint@15.11.0) dev: true @@ -14161,7 +14040,7 @@ packages: peerDependencies: stylelint: ^15.10.0 dependencies: - stylelint: 15.11.0(typescript@5.3.2) + stylelint: 15.11.0(typescript@5.3.3) dev: true /stylelint-config-standard@34.0.0(stylelint@15.11.0): @@ -14170,7 +14049,7 @@ packages: peerDependencies: stylelint: ^15.10.0 dependencies: - stylelint: 15.11.0(typescript@5.3.2) + stylelint: 15.11.0(typescript@5.3.3) stylelint-config-recommended: 13.0.0(stylelint@15.11.0) dev: true @@ -14180,7 +14059,7 @@ packages: peerDependencies: stylelint: ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 dependencies: - stylelint: 15.11.0(typescript@5.3.2) + stylelint: 15.11.0(typescript@5.3.3) dev: true /stylelint-order@6.0.3(stylelint@15.11.0): @@ -14190,7 +14069,7 @@ packages: dependencies: postcss: 8.4.31 postcss-sorting: 8.0.2(postcss@8.4.31) - stylelint: 15.11.0(typescript@5.3.2) + stylelint: 15.11.0(typescript@5.3.3) dev: true /stylelint-prettier@4.0.2(prettier@3.0.3)(stylelint@15.11.0): @@ -14202,7 +14081,7 @@ packages: dependencies: prettier: 3.0.3 prettier-linter-helpers: 1.0.0 - stylelint: 15.11.0(typescript@5.3.2) + stylelint: 15.11.0(typescript@5.3.3) dev: true /stylelint-scss@5.2.1(stylelint@15.11.0): @@ -14215,10 +14094,10 @@ packages: postcss-resolve-nested-selector: 0.1.1 postcss-selector-parser: 6.0.13 postcss-value-parser: 4.2.0 - stylelint: 15.11.0(typescript@5.3.2) + stylelint: 15.11.0(typescript@5.3.3) dev: true - /stylelint@15.11.0(typescript@5.3.2): + /stylelint@15.11.0(typescript@5.3.3): resolution: {integrity: sha512-78O4c6IswZ9TzpcIiQJIN49K3qNoXTM8zEJzhaTE/xRTCZswaovSEVIa/uwbOltZrk16X4jAxjaOhzz/hTm1Kw==} engines: {node: ^14.13.1 || >=16.0.0} hasBin: true @@ -14229,7 +14108,7 @@ packages: '@csstools/selector-specificity': 3.0.0(postcss-selector-parser@6.0.13) balanced-match: 2.0.0 colord: 2.9.3 - cosmiconfig: 8.3.6(typescript@5.3.2) + cosmiconfig: 8.3.6(typescript@5.3.3) css-functions-list: 3.2.1 css-tree: 2.3.1 debug: 4.3.4 @@ -14381,42 +14260,6 @@ packages: engines: {node: '>=6'} dev: true - /tar-fs@2.1.1: - resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} - dependencies: - chownr: 1.1.4 - mkdirp-classic: 0.5.3 - pump: 3.0.0 - tar-stream: 2.2.0 - dev: false - - /tar-fs@3.0.4: - resolution: {integrity: sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==} - dependencies: - mkdirp-classic: 0.5.3 - pump: 3.0.0 - tar-stream: 3.1.6 - dev: false - - /tar-stream@2.2.0: - resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} - engines: {node: '>=6'} - dependencies: - bl: 4.1.0 - end-of-stream: 1.4.4 - fs-constants: 1.0.0 - inherits: 2.0.4 - readable-stream: 3.6.2 - dev: false - - /tar-stream@3.1.6: - resolution: {integrity: sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==} - dependencies: - b4a: 1.6.4 - fast-fifo: 1.3.2 - streamx: 2.15.1 - dev: false - /tar@6.2.0: resolution: {integrity: sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==} engines: {node: '>=10'} @@ -14429,9 +14272,9 @@ packages: yallist: 4.0.0 dev: true - /teeny-request@8.0.3: - resolution: {integrity: sha512-jJZpA5He2y52yUhA7pyAGZlgQpcB+xLjcN0eUFxr9c8hP/H7uOXbBNVo/O0C/xVfJLJs680jvkFgVJEEvk9+ww==} - engines: {node: '>=12'} + /teeny-request@9.0.0: + resolution: {integrity: sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==} + engines: {node: '>=14'} requiresBuild: true dependencies: http-proxy-agent: 5.0.0 @@ -14445,8 +14288,8 @@ packages: dev: false optional: true - /tencentcloud-sdk-nodejs@4.0.739: - resolution: {integrity: sha512-LVKPQXto5toXnQvQ/6Zkp8oV8oU6EFAcS47bPFtxSrhGUeTAdzI5IH4X139l8yX2tB38tM3aN3edLQiONGyj7Q==} + /tencentcloud-sdk-nodejs@4.0.757: + resolution: {integrity: sha512-96Od56QayN1Mc+xwYEUlSVDpF/B8bs1wnqqslMaoM8KyQ4wr99nrKkBRIhMOVJutdAD/qEg9WYwQ7onwb4xb3A==} engines: {node: '>=10'} dependencies: form-data: 3.0.1 @@ -14592,15 +14435,6 @@ packages: os-tmpdir: 1.0.2 dev: true - /tmp@0.2.1: - resolution: {integrity: sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==} - engines: {node: '>=8.17.0'} - requiresBuild: true - dependencies: - rimraf: 3.0.2 - dev: false - optional: true - /tmpl@1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} dev: true @@ -14608,6 +14442,7 @@ packages: /to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} + dev: true /to-no-case@1.0.2: resolution: {integrity: sha512-Z3g735FxuZY8rodxV4gH7LxClE4H0hTIyHNIHdk+vpQxjLm0cwnKXq/OFVZ76SOQmto7txVcwSCwkU5kqp+FKg==} @@ -14707,13 +14542,13 @@ packages: resolution: {integrity: sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==} dev: false - /ts-api-utils@1.0.3(typescript@5.3.2): + /ts-api-utils@1.0.3(typescript@5.3.3): resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==} engines: {node: '>=16.13.0'} peerDependencies: typescript: '>=4.2.0' dependencies: - typescript: 5.3.2 + typescript: 5.3.3 dev: true /ts-custom-error@2.2.2: @@ -14726,8 +14561,8 @@ packages: resolution: {integrity: sha512-PGcnJoTBnVGy6yYNFxWVNkdcAuAMstvutN9MgDJIV6L0oG8fB+ZNNy1T+wJzah8RPGor1mZuPQkVfXNDpy9eHA==} dev: true - /ts-node@10.9.1(@swc/core@1.3.94)(@types/node@20.5.1)(typescript@5.3.2): - resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + /ts-node@10.9.2(@swc/core@1.3.94)(@types/node@20.10.4)(typescript@5.3.3): + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} hasBin: true peerDependencies: '@swc/core': '>=1.2.50' @@ -14746,20 +14581,19 @@ packages: '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 20.5.1 + '@types/node': 20.10.4 acorn: 8.10.0 acorn-walk: 8.2.0 arg: 4.1.3 create-require: 1.1.1 diff: 4.0.2 make-error: 1.3.6 - typescript: 5.3.2 + typescript: 5.3.3 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 - dev: true - /ts-node@10.9.1(@swc/core@1.3.94)(@types/node@20.9.3)(typescript@5.3.2): - resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + /ts-node@10.9.2(@swc/core@1.3.94)(@types/node@20.5.1)(typescript@5.3.3): + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} hasBin: true peerDependencies: '@swc/core': '>=1.2.50' @@ -14778,16 +14612,17 @@ packages: '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 20.9.3 + '@types/node': 20.5.1 acorn: 8.10.0 acorn-walk: 8.2.0 arg: 4.1.3 create-require: 1.1.1 diff: 4.0.2 make-error: 1.3.6 - typescript: 5.3.2 + typescript: 5.3.3 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 + dev: true /ts-xor@1.3.0: resolution: {integrity: sha512-RLXVjliCzc1gfKQFLRpfeD0rrWmjnSTgj7+RFhoq3KRkUYa8LE/TIidYOzM5h+IdFBDSjjSgk9Lto9sdMfDFEA==} @@ -14850,14 +14685,14 @@ packages: /tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} - /tsutils@3.21.0(typescript@5.3.2): + /tsutils@3.21.0(typescript@5.3.3): resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} peerDependencies: typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' dependencies: tslib: 1.14.1 - typescript: 5.3.2 + typescript: 5.3.3 dev: true /tunnel-agent@0.6.0: @@ -14870,15 +14705,6 @@ packages: resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} dev: false - /type-check@0.3.2: - resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} - engines: {node: '>= 0.8.0'} - requiresBuild: true - dependencies: - prelude-ls: 1.1.2 - dev: false - optional: true - /type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -14963,7 +14789,7 @@ packages: for-each: 0.3.3 is-typed-array: 1.1.12 - /typeorm@0.3.17(ioredis@5.3.2)(pg@8.11.3)(ts-node@10.9.1): + /typeorm@0.3.17(ioredis@5.3.2)(pg@8.11.3)(ts-node@10.9.2): resolution: {integrity: sha512-UDjUEwIQalO9tWw9O2A4GU+sT3oyoUXheHJy4ft+RFdnRdQctdQ34L9SqE2p7LdwzafHx1maxT+bqXON+Qnmig==} engines: {node: '>= 12.9.0'} hasBin: true @@ -15033,9 +14859,9 @@ packages: ioredis: 5.3.2 mkdirp: 2.1.6 pg: 8.11.3 - reflect-metadata: 0.1.13 + reflect-metadata: 0.1.14 sha.js: 2.4.11 - ts-node: 10.9.1(@swc/core@1.3.94)(@types/node@20.9.3)(typescript@5.3.2) + ts-node: 10.9.2(@swc/core@1.3.94)(@types/node@20.10.4)(typescript@5.3.3) tslib: 2.6.2 uuid: 9.0.1 yargs: 17.7.2 @@ -15049,8 +14875,8 @@ packages: hasBin: true dev: true - /typescript@5.3.2: - resolution: {integrity: sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==} + /typescript@5.3.3: + resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} engines: {node: '>=14.17'} hasBin: true @@ -15058,20 +14884,6 @@ packages: resolution: {integrity: sha512-znuyCIXzl8ciS3+y3fHJI/2OhQIXbXw9MWC/o3qwyR+RGppjZHrM27CGFSKCJXi2Kctiz537iOu2KnXs1lMQhw==} dev: true - /uc.micro@1.0.6: - resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} - requiresBuild: true - dev: false - optional: true - - /uglify-js@3.17.4: - resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==} - engines: {node: '>=0.8.0'} - hasBin: true - requiresBuild: true - dev: false - optional: true - /uid2@0.0.4: resolution: {integrity: sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA==} dev: false @@ -15095,12 +14907,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /underscore@1.13.6: - resolution: {integrity: sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==} - requiresBuild: true - dev: false - optional: true - /undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} @@ -15694,13 +15500,6 @@ packages: winston-transport: 4.6.0 dev: false - /word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} - requiresBuild: true - dev: false - optional: true - /wrap-ansi@6.2.0: resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} engines: {node: '>=8'} @@ -15793,12 +15592,6 @@ packages: resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} dev: true - /xmlcreate@2.0.4: - resolution: {integrity: sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==} - requiresBuild: true - dev: false - optional: true - /xss@1.0.14: resolution: {integrity: sha512-og7TEJhXvn1a7kzZGQ7ETjdQVS2UfZyTlsEdDOqvQF7GoxNfY+0YLCzBy1kPdsDDx4QuNAonQPddpsn6Xl/7sw==} engines: {node: '>= 0.10.0'} diff --git a/src/addon/addon.spec.ts b/src/addon/addon.spec.ts new file mode 100644 index 00000000..3435137c --- /dev/null +++ b/src/addon/addon.spec.ts @@ -0,0 +1,9 @@ +import { hello } from '@/addon/index'; +import { describe, expect, it } from '@jest/globals'; + +describe('Addon', () => { + it('hello', () => { + const msg = hello('World'); + expect(msg).toBe('Hello World!'); + }); +}); diff --git a/src/addon/index.ts b/src/addon/index.ts index 68796614..593af8bf 100644 --- a/src/addon/index.ts +++ b/src/addon/index.ts @@ -1,7 +1,5 @@ -import type { Exif } from './types/Exif'; - const api = require('bindings')('api'); -export const getEXIF = (path: string): Exif => { - return api.getEXIF(path); +export const hello = (name: string) => { + return api.hello(name); }; diff --git a/src/addon/types/Exif.ts b/src/addon/types/Exif.ts deleted file mode 100644 index 1e5f7f05..00000000 --- a/src/addon/types/Exif.ts +++ /dev/null @@ -1,86 +0,0 @@ -export interface Exif { - ImageWidth: number; - ImageHeight: number; - RelatedImageWidth: number; - RelatedImageHeight: number; - ImageDescription: string; - Make: string; - Model: string; - SerialNumber: string; - Orientation: number; - XResolution: number; - YResolution: number; - ResolutionUnit: number; - BitsPerSample: number; - Software: string; - DateTime: string; - DateTimeOriginal: string; - DateTimeDigitized: string; - SubSecTimeOriginal: string; - ExposureTime: number; - Copyright: string; - FNumber: number; - ExposureProgram: number; - ISOSpeedRatings: number; - ShutterSpeedValue: number; - ApertureValue: number; - BrightnessValue: number; - ExposureBiasValue: number; - SubjectDistance: number; - FocalLength: number; - Flash: number; - SubjectArea: number[]; - MeteringMode: number; - LightSource: number; - ProjectionType: number; - Calibration: Calibration; - LensInfo: LensInfo; - GeoLocation: GeoLocation; - GPano: GPano; -} - -export interface Calibration { - FocalLength: number; - OpticalCenterX: number; - OpticalCenterY: number; -} - -export interface GPano { - PosePitchDegrees: number; - PoseRollDegrees: number; -} - -export interface GeoLocation { - Latitude: number; - Longitude: number; - Altitude: number; - AltitudeRef: number; - RelativeAltitude: number; - RollDegree: number; - PitchDegree: number; - YawDegree: number; - SpeedX: number; - SpeedY: number; - SpeedZ: number; - AccuracyXY: number; - AccuracyZ: number; - GPSDOP: number; - GPSDifferential: number; - GPSMapDatum: string; - GPSTimeStamp: string; - GPSDateStamp: string; -} - -export interface LensInfo { - FStopMin: number; - FStopMax: number; - FocalLengthMin: number; - FocalLengthMax: number; - DigitalZoomRatio: number; - FocalLengthIn35mm: number; - FocalPlaneXResolution: number; - FocalPlaneYResolution: number; - FocalPlaneResolutionUnit: number; - Make: string; - Model: string; -} diff --git a/src/asset/asset.service.ts b/src/asset/asset.service.ts index 4994813f..5ac53d9a 100644 --- a/src/asset/asset.service.ts +++ b/src/asset/asset.service.ts @@ -1,4 +1,3 @@ -import { getEXIF } from '@/addon'; import type { QueryAssetsDto } from '@/asset/dto/query-assets.dto'; import { Asset } from '@/asset/entities/asset.entity'; import { BucketService } from '@/bucket/bucket.service'; @@ -6,6 +5,7 @@ import type { CosBucket } from '@/bucket/entities/bucket.entity'; import { LoggerService } from '@/common/logger/logger.service'; import { AZUKI_ASSET_PATH, getBucketAssetPath } from '@/constants/asset_constants'; import { ScheduleType } from '@/enum/ScheduleType'; +import { getEXIF } from '@/lib/exif'; import { InstagramBotService } from '@/libs/instagram-bot'; import { PinterestBotService } from '@/libs/pinterest-bot'; import type { PinterestInterface } from '@/libs/pinterest-bot'; @@ -250,7 +250,7 @@ export class AssetService extends BaseService { ensureFileSync(path); writeFileSync(path, buffer); } - _asset.exif = getEXIF(path); + _asset.exif = await getEXIF(path); _asset.metadata = metadata; const { text } = await this.ocrService.recognize(path); _asset.alt = text; diff --git a/src/asset/entities/asset.entity.ts b/src/asset/entities/asset.entity.ts index 5c0c3431..07c67bf7 100644 --- a/src/asset/entities/asset.entity.ts +++ b/src/asset/entities/asset.entity.ts @@ -1,4 +1,5 @@ import { ApiProperty } from '@nestjs/swagger'; +import type { Exif } from 'exif-reader'; import { Metadata } from 'sharp'; import { BeforeInsert, @@ -13,7 +14,6 @@ import { UpdateDateColumn, } from 'typeorm'; import { User } from '@/user/entities/user.entity'; -import { Exif } from '@/addon/types/Exif'; import { CosBucket } from '@/bucket/entities/bucket.entity'; export const AssetStyles = { @@ -93,7 +93,7 @@ export class Asset { @Column({ type: 'jsonb', select: false }) @ApiProperty() - exif: Exif; + exif: Exif | null; @Column({ type: 'jsonb', select: false }) @ApiProperty() diff --git a/src/lib/exif.ts b/src/lib/exif.ts index 7e36a543..4b17d8e4 100644 --- a/src/lib/exif.ts +++ b/src/lib/exif.ts @@ -6,7 +6,7 @@ import utc from 'dayjs/plugin/utc'; dayjs.extend(utc); -export const getEXIF = async (file: Buffer) => { +export const getEXIF = async (file: Buffer | string) => { const s = sharp(file); const metadata = await s.metadata(); const { exif } = metadata;