Page MenuHomePhabricator

D12814.id30793.diff
No OneTemporary

D12814.id30793.diff

diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -281,13 +281,9 @@
'rsrc/image/icon/fatcow/source/mobile.png' => 'f1321264',
'rsrc/image/icon/fatcow/source/tablet.png' => '49396799',
'rsrc/image/icon/fatcow/source/web.png' => '136ccb5d',
- 'rsrc/image/icon/fatcow/thumbnails/default.p100.png' => '7d490b01',
'rsrc/image/icon/fatcow/thumbnails/default280x210.png' => '43e8926a',
- 'rsrc/image/icon/fatcow/thumbnails/image.p100.png' => 'da23cf97',
'rsrc/image/icon/fatcow/thumbnails/image280x210.png' => '91ae054a',
- 'rsrc/image/icon/fatcow/thumbnails/pdf.p100.png' => '87d5e065',
'rsrc/image/icon/fatcow/thumbnails/pdf280x210.png' => '1c585653',
- 'rsrc/image/icon/fatcow/thumbnails/zip.p100.png' => '6ea5aae4',
'rsrc/image/icon/fatcow/thumbnails/zip280x210.png' => 'dfda5b8e',
'rsrc/image/icon/lightbox/close-2.png' => 'cc40e7c8',
'rsrc/image/icon/lightbox/close-hover-2.png' => 'fb5d6d9e',
diff --git a/src/applications/files/PhabricatorImageTransformer.php b/src/applications/files/PhabricatorImageTransformer.php
--- a/src/applications/files/PhabricatorImageTransformer.php
+++ b/src/applications/files/PhabricatorImageTransformer.php
@@ -51,20 +51,6 @@
));
}
- public function executePreviewTransform(
- PhabricatorFile $file,
- $size) {
-
- $image = $this->generatePreview($file, $size);
-
- return PhabricatorFile::newFromFileData(
- $image,
- array(
- 'name' => 'preview-'.$file->getName(),
- 'canCDN' => true,
- ));
- }
-
public function executeConpherenceTransform(
PhabricatorFile $file,
$top,
@@ -188,37 +174,6 @@
}
- public static function getPreviewDimensions(PhabricatorFile $file, $size) {
- $metadata = $file->getMetadata();
- $x = idx($metadata, PhabricatorFile::METADATA_IMAGE_WIDTH);
- $y = idx($metadata, PhabricatorFile::METADATA_IMAGE_HEIGHT);
-
- if (!$x || !$y) {
- $data = $file->loadFileData();
- $src = imagecreatefromstring($data);
-
- $x = imagesx($src);
- $y = imagesy($src);
- }
-
- $scale = min($size / $x, $size / $y, 1);
-
- $dx = max($size / 4, $scale * $x);
- $dy = max($size / 4, $scale * $y);
-
- $sdx = $scale * $x;
- $sdy = $scale * $y;
-
- return array(
- 'x' => $x,
- 'y' => $y,
- 'dx' => $dx,
- 'dy' => $dy,
- 'sdx' => $sdx,
- 'sdy' => $sdy,
- );
- }
-
public static function getScaleForCrop(
PhabricatorFile $file,
$des_width,
@@ -241,31 +196,6 @@
return $scale;
}
- private function generatePreview(PhabricatorFile $file, $size) {
- $data = $file->loadFileData();
- $src = imagecreatefromstring($data);
-
- $dimensions = self::getPreviewDimensions($file, $size);
- $x = $dimensions['x'];
- $y = $dimensions['y'];
- $dx = $dimensions['dx'];
- $dy = $dimensions['dy'];
- $sdx = $dimensions['sdx'];
- $sdy = $dimensions['sdy'];
-
- $dst = $this->getBlankDestinationFile($dx, $dy);
-
- imagecopyresampled(
- $dst,
- $src,
- ($dx - $sdx) / 2, ($dy - $sdy) / 2,
- 0, 0,
- $sdx, $sdy,
- $x, $y);
-
- return self::saveImageDataInAnyFormat($dst, $file->getMimeType());
- }
-
private function applyMemeToFile(
PhabricatorFile $file,
$upper_text,
diff --git a/src/applications/files/controller/PhabricatorFileTransformController.php b/src/applications/files/controller/PhabricatorFileTransformController.php
--- a/src/applications/files/controller/PhabricatorFileTransformController.php
+++ b/src/applications/files/controller/PhabricatorFileTransformController.php
@@ -85,12 +85,6 @@
case 'thumb-280x210':
$xformed_file = $this->executeThumbTransform($file, 280, 210);
break;
- case 'preview-100':
- $xformed_file = $this->executePreviewTransform($file, 100);
- break;
- case 'preview-220':
- $xformed_file = $this->executePreviewTransform($file, 220);
- break;
default:
return new Aphront400Response();
}
@@ -132,9 +126,6 @@
case 'thumb-280x210':
$suffix = '280x210';
break;
- case 'preview-100':
- $suffix = '.p100';
- break;
default:
throw new Exception('Unsupported transformation type!');
}
@@ -163,11 +154,6 @@
return $file->getRedirectResponse();
}
- private function executePreviewTransform(PhabricatorFile $file, $size) {
- $xformer = new PhabricatorImageTransformer();
- return $xformer->executePreviewTransform($file, $size);
- }
-
private function executeThumbTransform(PhabricatorFile $file, $x, $y) {
$xformer = new PhabricatorImageTransformer();
return $xformer->executeThumbTransform($file, $x, $y);
diff --git a/src/applications/files/markup/PhabricatorEmbedFileRemarkupRule.php b/src/applications/files/markup/PhabricatorEmbedFileRemarkupRule.php
--- a/src/applications/files/markup/PhabricatorEmbedFileRemarkupRule.php
+++ b/src/applications/files/markup/PhabricatorEmbedFileRemarkupRule.php
@@ -107,11 +107,17 @@
break;
case 'thumb':
default:
- $attrs['src'] = $file->getPreview220URI();
- $dimensions =
- PhabricatorImageTransformer::getPreviewDimensions($file, 220);
- $attrs['width'] = $dimensions['dx'];
- $attrs['height'] = $dimensions['dy'];
+ $preview_key = PhabricatorFileThumbnailTransform::TRANSFORM_PREVIEW;
+ $xform = PhabricatorFileTransform::getTransformByKey($preview_key);
+ $attrs['src'] = $file->getURIForTransform($xform);
+
+ $dimensions = $xform->getTransformedDimensions($file);
+ if ($dimensions) {
+ list($x, $y) = $dimensions;
+ $attrs['width'] = $x;
+ $attrs['height'] = $y;
+ }
+
$image_class = 'phabricator-remarkup-embed-image';
break;
}
diff --git a/src/applications/files/storage/PhabricatorFile.php b/src/applications/files/storage/PhabricatorFile.php
--- a/src/applications/files/storage/PhabricatorFile.php
+++ b/src/applications/files/storage/PhabricatorFile.php
@@ -788,14 +788,6 @@
return $this->getTransformedURI('thumb-profile');
}
- public function getPreview100URI() {
- return $this->getTransformedURI('preview-100');
- }
-
- public function getPreview220URI() {
- return $this->getTransformedURI('preview-220');
- }
-
public function getThumb280x210URI() {
return $this->getTransformedURI('thumb-280x210');
}
diff --git a/src/applications/files/transform/PhabricatorFileImageTransform.php b/src/applications/files/transform/PhabricatorFileImageTransform.php
--- a/src/applications/files/transform/PhabricatorFileImageTransform.php
+++ b/src/applications/files/transform/PhabricatorFileImageTransform.php
@@ -8,6 +8,16 @@
private $imageX;
private $imageY;
+ /**
+ * Get an estimate of the transformed dimensions of a file.
+ *
+ * @param PhabricatorFile File to transform.
+ * @return list<int, int>|null Width and height, if available.
+ */
+ public function getTransformedDimensions(PhabricatorFile $file) {
+ return null;
+ }
+
public function canApplyTransform(PhabricatorFile $file) {
if (!$file->isViewableImage()) {
return false;
diff --git a/src/applications/files/transform/PhabricatorFileThumbnailTransform.php b/src/applications/files/transform/PhabricatorFileThumbnailTransform.php
--- a/src/applications/files/transform/PhabricatorFileThumbnailTransform.php
+++ b/src/applications/files/transform/PhabricatorFileThumbnailTransform.php
@@ -65,6 +65,59 @@
$dst_x = $this->dstX;
$dst_y = $this->dstY;
+ $dimensions = $this->computeDimensions(
+ $src_x,
+ $src_y,
+ $dst_x,
+ $dst_y);
+
+ $copy_x = $dimensions['copy_x'];
+ $copy_y = $dimensions['copy_y'];
+ $use_x = $dimensions['use_x'];
+ $use_y = $dimensions['use_y'];
+ $dst_x = $dimensions['dst_x'];
+ $dst_y = $dimensions['dst_y'];
+
+ return $this->applyCropAndScale(
+ $dst_x,
+ $dst_y,
+ ($src_x - $copy_x) / 2,
+ ($src_y - $copy_y) / 2,
+ $copy_x,
+ $copy_y,
+ $use_x,
+ $use_y);
+ }
+
+
+ public function getTransformedDimensions(PhabricatorFile $file) {
+ $dst_x = $this->dstX;
+ $dst_y = $this->dstY;
+
+ // If this is transform has fixed dimensions, we can trivially predict
+ // the dimensions of the transformed file.
+ if ($dst_y !== null) {
+ return array($dst_x, $dst_y);
+ }
+
+ $src_x = $file->getImageWidth();
+ $src_y = $file->getImageHeight();
+
+ if (!$src_x || !$src_y) {
+ return null;
+ }
+
+ $dimensions = $this->computeDimensions(
+ $src_x,
+ $src_y,
+ $dst_x,
+ $dst_y);
+
+ return array($dimensions['dst_x'], $dimensions['dst_y']);
+ }
+
+
+ private function computeDimensions($src_x, $src_y, $dst_x, $dst_y) {
if ($dst_y === null) {
// If we only have one dimension, it represents a maximum dimension.
// The other dimension of the transform is scaled appropriately, except
@@ -115,17 +168,17 @@
$use_y = $dst_y;
}
- return $this->applyCropAndScale(
- $dst_x,
- $dst_y,
- ($src_x - $copy_x) / 2,
- ($src_y - $copy_y) / 2,
- $copy_x,
- $copy_y,
- $use_x,
- $use_y);
+ return array(
+ 'copy_x' => $copy_x,
+ 'copy_y' => $copy_y,
+ 'use_x' => $use_x,
+ 'use_y' => $use_y,
+ 'dst_x' => $dst_x,
+ 'dst_y' => $dst_y,
+ );
}
+
public function getDefaultTransform(PhabricatorFile $file) {
$x = (int)$this->dstX;
$y = (int)$this->dstY;
diff --git a/src/applications/files/transform/PhabricatorFileTransform.php b/src/applications/files/transform/PhabricatorFileTransform.php
--- a/src/applications/files/transform/PhabricatorFileTransform.php
+++ b/src/applications/files/transform/PhabricatorFileTransform.php
@@ -45,4 +45,18 @@
return $map;
}
+ public static function getTransformByKey($key) {
+ $all = self::getAllTransforms();
+
+ $xform = idx($all, $key);
+ if (!$xform) {
+ throw new Exception(
+ pht(
+ 'No file transform with key "%s" exists.',
+ $key));
+ }
+
+ return $xform;
+ }
+
}
diff --git a/src/applications/pholio/view/PholioMockThumbGridView.php b/src/applications/pholio/view/PholioMockThumbGridView.php
--- a/src/applications/pholio/view/PholioMockThumbGridView.php
+++ b/src/applications/pholio/view/PholioMockThumbGridView.php
@@ -114,28 +114,34 @@
private function renderThumbnail(PholioImage $image) {
$thumbfile = $image->getFile();
+ $preview_key = PhabricatorFileThumbnailTransform::TRANSFORM_THUMBGRID;
+ $xform = PhabricatorFileTransform::getTransformByKey($preview_key);
+
+ $attributes = array(
+ 'class' => 'pholio-mock-thumb-grid-image',
+ 'src' => $thumbfile->getURIForTransform($xform),
+ );
+
if ($image->getFile()->isViewableImage()) {
- $dimensions = PhabricatorImageTransformer::getPreviewDimensions(
- $thumbfile,
- 100);
+ $dimensions = $xform->getTransformedDimensions($thumbfile);
+ if ($dimensions) {
+ list($x, $y) = $dimensions;
+ $attributes += array(
+ 'width' => $x,
+ 'height' => $y,
+ 'style' => 'top: '.floor((100 - $y) / 2).'px',
+ );
+ }
} else {
// If this is a PDF or a text file or something, we'll end up using a
// generic thumbnail which is always sized correctly.
- $dimensions = array(
- 'sdx' => 100,
- 'sdy' => 100,
+ $attributes += array(
+ 'width' => 100,
+ 'height' => 100,
);
}
- $tag = phutil_tag(
- 'img',
- array(
- 'width' => $dimensions['sdx'],
- 'height' => $dimensions['sdy'],
- 'src' => $thumbfile->getPreview100URI(),
- 'class' => 'pholio-mock-thumb-grid-image',
- 'style' => 'top: '.floor((100 - $dimensions['sdy'] ) / 2).'px',
- ));
+ $tag = phutil_tag('img', $attributes);
$classes = array('pholio-mock-thumb-grid-item');
if ($image->getIsObsolete()) {
diff --git a/webroot/rsrc/image/icon/fatcow/thumbnails/default.p100.png b/webroot/rsrc/image/icon/fatcow/thumbnails/default.p100.png
deleted file mode 100644
index f713c2398bafd8dad1d22b179532f0c3920c7dd6..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
literal 1720
zc%17D@N?(olHy`uVBq!ia0vp^DIm<j1|$m}O$`B3k|nMYCBgY=CFO}lsSJ)O`AMk?
zp1FzXsX?iUDV2pMQ*9U+m{l@EB1$5BeXNr6bM+EIYV;~{3m8Da#=fE;F*!T6L?J0P
zJu}Z%>HY5gN(z}Nwo2iqz6QPp&Z!xh9#uuD!Bu`C$yM3OmMKd1b_zBXRzL%CQ%e#R
zDspr3imfVamB8j&0ofp7eI*63l9Fs&C5WRUd;=7m^NUgyO!bU)lMM_F70k@^3{6bU
z%nWrDj0_Bo^bLT>OxMuF%GAut$Xo#mlz_GsrKDK}xwt{?0`hE?GD=Dctn~HE%ggo3
zjrH=2()A53EiFN27#ZmTRp=I1=9MH?=;jqG!%T2VElw`VEGWs$&r<;L6O-~wOKg>t
zU|z^AfE$}v3=Jk=fazBx7U&!58R#P^^!3HBG&dKny0|1LH4VS&;*iRMRQ;gT;{4L0
zWMIUlDT6c@SUDG^CYIzEh2-bwz(O$~BfliSI3vG6!8zDWLBlsOIWrF=pb6ID>ucqi
zS6q^qmz?V9Vygrc(aX$Cv2t`XF*kN}vvhTKax^q_HMX#Da&~q!Ffep6HgGmIGlA)K
z$xklLP0cHT=}kfCb;PL`lo%koQ;RaoQd8WD@^clyp0>)w?G|&~Zh`1c!R;0coO<<v
zj?qVpYM2l({eYP8gbU=rlYVL*FufN66ZWQ+#eu;5qUGu07*cWT&8>}jmjgtOeXPz^
zH_>WIV-R&=kI?YR;nB5Tq2S?N?r^4qlTAe+DftO&MMK90B}VW0jA2W-6gO^RVr*Tu
z)~n;}&TW%hl^z{)JpStc>UE1&tjqrWym;N)BW{5y9rGd_7!(^AoER8e7??O1Sp@o+
z6j%ftI20NLpb{vuPy(dn-)px>=^p!<of~d$G=AH6d*7SeFRHIi@!j#`>&2z3KYhFI
zcY1}5<XyK+=}F92f3IKUxOvMTOR2rLbFAhsdQ-h%OOgAeQwGnD?hZ|!yz1raCtOdz
zetNQF<Mw$oU!0ti88d&~dDpYYu06h4`7_kL`t+wQ+b-qJ{*=n?eW|X=&TUgn`FWeo
zf0m}|&9PC@2>yC%ZrbDgsZ1ViQ=S}PE1KfH@9*=D>7Vz=y}aRZb5HEgyfig_aW+@m
z4*j)SuU{++<4l=ycDBgU%H&;o#a&q<TNUoUmXAMIQ+{+x>Js6uE&AtWR=+bAzS^~A
zJ#TT`t?Q4@7Jt39x0N;0>FFQIjP(;7&Q+K%ylp4Ao3$wSRm;Zh^Jm|a-xc4MXmfG<
z-b=2P;S)FVozQ!y{)@GcGxcD9_Uvab|IDm-GsREh`h5<C-E*8bHB@YRla+mY&6@n<
zS1)Q$*up+<?uyde3qx-TehKdo-@Y)%{rtbe{P-#EF29}&+<#VN<!;5jXojw~ya2O@
zp7aaVx9a=?+#YtKOdX4?o$pKE+r=oEz;{zy^Nh?S_l!u(bBYZscJhCmG<%m!T4{8{
zx8-t6-Z<<y6*S??3*Ei{MeOIFQeGHx>&?r>t5TVs%AHJ?dC7dNQOm`^YSw%$v8Aau
z@A=DRFG_t{z%RbE{~Y`J2`d=<w=kXEI#I^s``x(*=U-J*_@&=)wQ0(w<L|=#WF=4S
z+Rkut+QkD~`0Oh7?tg2SclPyR)!8-Wr`P^&zqW6|m)(1lKNZEe<#PNz`u2mlq<qT#
z>kKdXmpth@a#x)1W&EEh8x?=wV}mC!P})LDZ;;f8GfAfOKikg0%y5i#RrbRz%hEt~
NiKnZd%Q~loCIEmkkVF6g
diff --git a/webroot/rsrc/image/icon/fatcow/thumbnails/image.p100.png b/webroot/rsrc/image/icon/fatcow/thumbnails/image.p100.png
deleted file mode 100644
index f5fa35ab087de71c9429b3d419ae0506cf2290c1..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
literal 2167
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
Fe**?UU)BHs
diff --git a/webroot/rsrc/image/icon/fatcow/thumbnails/pdf.p100.png b/webroot/rsrc/image/icon/fatcow/thumbnails/pdf.p100.png
deleted file mode 100644
index ad3a39b490701b073d84d8e84756782481356adf..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
literal 2363
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
DOoYN+
diff --git a/webroot/rsrc/image/icon/fatcow/thumbnails/zip.p100.png b/webroot/rsrc/image/icon/fatcow/thumbnails/zip.p100.png
deleted file mode 100644
index 86fa739b3b5bcbbafabf59b4aa990df899d2f954..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
literal 2067
zc$|Gz3s6(X8b08o&|Z|*f)uem#;7RfNfJ#;cqIrCl43{{1{Fhc0;e%KF*!hZBv|C~
zl2XM`Yb#I+SbR_<tvW%GDpN#)iVq%AoKmTXh+O4SfnMOAh*0Ow(4BL3_y7Ly`}g17
ze`d2o1%VE4yS@zofCDdxE5t^b^|xD$_3DQOB5e2o4G2fW5ILG4(LjKo42gz7o>CG6
z2_cCrao=^w3jh}2VNp05&JSTp5hYP#<q&mBHDGOCK038Ts(?^18j68cY}|h?*5N={
z#>VZS^T~WQ2a1J*k~C0Ql0YO)Qb?IHoR2r?rDI_Mln^Qbb;`XeElbD7y^71i=2n=5
z17A^41sgY$R5(8r<RBUdq!T>}QZj`CG8jY(jm}_DHiA?#g-Rl0AA>-lvFHpIbrbly
z;jq;-GC51g-ST=Z%wpqWQB=($krEOThzXuVL=!`zFquqi3@Vj?F$mg36)MpYRNB?E
z5x9_6s)5xgjHp1XEr~|rP&N)Xy9K3sF04xX`k1f-Bk3e+5`{=6y+P#j|Cy>(&at(q
z5R(5hTPsRbLnI-jMdCD4?Be9BtztEcqk$wSq7fm;-q}+OjYUvI8;htxP8b7p=S!rp
z$_lK1rQq{fJe3xesH6~&%f?{{5r$<f&L)3<29-_@;Q0GdC;^_EH~Vuqeq=I*>q+L&
z8MIj~7m>y(Ar(5SmHn-y%&WB)!;Biz!10i5iw04GuQtts=gox{Fn=yHTG_n0(6-F0
zC1J^s{_m=1A*_C^)49UMjJeW>R9L-hu)=oMU9km#h5zPp{Y1LXf#bo7W!v7rcB|HN
z?GaJs(p=@vtcOn*xI6jnt0JO1{7U0Wh&!`E724xJX_r%el8{reD?4)6m`#dPT*<pp
z)r_`4anKFj%|c$qb*=}$TQENTyZTsiOn&p^Bd@{26HPDmX#<BF-UsX!f`F}!-F{!d
z7IfTiHD~%az`tFy;GC;D!ptzZmm3o#v1Mm#4p0r{{@Z+N!uIAp72*zqm2`fAMI=9+
z{#a4o_hk9><jJlgamtuyzy8dBnZ+sYzvi~;d)f%8Yx|!)8`YYRr~Y-bFrzxUy06%b
zK69wsjU&EPDH{9F7?PtdZEUezJ-yiDQWF1{>MzjlmQ|YjVHrb-8w@U<((gR#>y6iC
zeb4ih_wO#Rs*PQ|h$+h`KJ6NUcgtqxg~fDTn;f4q*zYq+$*o#`P|x`hIIX6p#-*vP
z!?)V|q(x@I2d{w4m%X*Sr-mN+e0DbRI$pnr)IT_w=U@y6vd;r|fCG-td~~4#hF-kp
z$gumPM7n!myvm{xRJ-Pk`r>JDrE6~Km$240jsA0q#r|5zRYrS_QIJflD=l@toHy86
z#QrsP*L$C5nqE#f)%kdpMYu0>JSl40f6OpgLs!K1^@~sKUSG9#&5O&m$#6X`f%y?p
zp8OU#z0!o@5B+RDXD@C~e7Gp&lUs7{_7Ws&9elUp^M>z4_Ina+8#ii#IH@j0LnWC5
zOWE9swW%rJBYRu_@YcWEan37j)Z3%}+$fW~y=z-<XiM)znj3D9+mjuB%z=#Fdmo$^
zboQ+>eQ2hVeLvhG6i$6=k91XSxXoO*WO}@D%GAE?3cmeVZ@-1Fj`(KlHw6>VyTOkx
zp77~Uk>=SR+Ma%9f}XXcw&(VN%#p!K7rk3?x9Lw$wqc}W#G<>`8Q=lHevO)|TNO3T
z0jJ@<CqKr>D_33kee;#-k-(^BJ2Tzx*e-?pj-=lxB2WBbzw+aFV_Q|Eg<N#E_TtOf
zTZ0d1zx0@Tvr3~c#^Fj}6g4^%`^tLO3BKN*S6(+Be=sex*)=QghqE#jG;}Sv$JiT}
z^^;Am`nYH#8}AGuKYH8mDu40b(c1NQ+v1a?4;{4YGSl_KLBrQyeOq>vR_WH>U{j_S
zJGZjMM{{`iTla$3EY5!(@-*EyEoZ|}D^OOrO7SE=U?<Ebmux+C%E`ktZ5ILD$uCHn
zEG`^t`abGk-CgEkhsVKnxq(g#(l;pn%y+17T<Kmkw)KdCQ1q?5R|(unJ0u=9R^0G!
zz0|$v(EY;|1?MX}%PVcFU2@O)j{Fp}ymCseI9Plz{GGC9^LTG#7WIqB$Wgb|T`vg1
zZ5Qa|j<J>ucJ!J}ksT&wh4@j%Z>9&2lSx2h^Zqh(L_^!{6BoXct>{UfUIMoKHoW2l
z;0ppaj&{DlLR&}RGhiWR&h&4BbFNu%&Lz9qe*stkgz$I|J~eoETc2rOfPnjh|DLq}
E0V)1F#Q*>R

File Metadata

Mime Type
text/plain
Expires
Mar 15 2025, 5:35 PM (5 w, 3 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7699414
Default Alt Text
D12814.id30793.diff (21 KB)

Event Timeline