Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15403193
D12818.id30808.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
29 KB
Referenced Files
None
Subscribers
None
D12818.id30808.diff
View Options
diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -33,7 +33,7 @@
'rsrc/css/aphront/typeahead-browse.css' => 'd8581d2c',
'rsrc/css/aphront/typeahead.css' => '0e403212',
'rsrc/css/application/almanac/almanac.css' => 'dbb9b3af',
- 'rsrc/css/application/auth/auth.css' => '1e655982',
+ 'rsrc/css/application/auth/auth.css' => 'fee03832',
'rsrc/css/application/base/main-menu-view.css' => '663e3810',
'rsrc/css/application/base/notification-menu.css' => '3c9d8aa1',
'rsrc/css/application/base/phabricator-application-launch-view.css' => '16ca323f',
@@ -281,10 +281,6 @@
'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/default280x210.png' => '43e8926a',
- 'rsrc/image/icon/fatcow/thumbnails/image280x210.png' => '91ae054a',
- 'rsrc/image/icon/fatcow/thumbnails/pdf280x210.png' => '1c585653',
- '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',
'rsrc/image/icon/lightbox/left-arrow-2.png' => '8426133b',
@@ -495,7 +491,7 @@
'aphront-tooltip-css' => '7672b60f',
'aphront-two-column-view-css' => '16ab3ad2',
'aphront-typeahead-control-css' => '0e403212',
- 'auth-css' => '1e655982',
+ 'auth-css' => 'fee03832',
'changeset-view-manager' => '58562350',
'conduit-api-css' => '7bc725c4',
'config-options-css' => '7fedf08b',
diff --git a/src/applications/auth/view/PhabricatorAuthAccountView.php b/src/applications/auth/view/PhabricatorAuthAccountView.php
--- a/src/applications/auth/view/PhabricatorAuthAccountView.php
+++ b/src/applications/auth/view/PhabricatorAuthAccountView.php
@@ -89,13 +89,17 @@
$account_uri);
}
- $image_uri = $account->getProfileImageFile()->getProfileThumbURI();
+ $image_file = $account->getProfileImageFile();
+ $xform = PhabricatorFileTransform::getTransformByKey(
+ PhabricatorFileThumbnailTransform::TRANSFORM_PROFILE);
+ $image_uri = $image_file->getURIForTransform($xform);
+ list($x, $y) = $xform->getTransformedDimensions($image_file);
return phutil_tag(
'div',
array(
'class' => 'auth-account-view',
- 'style' => 'background-image: url('.$image_uri.')',
+ 'style' => 'background-image: url('.$image_uri.');',
),
$content);
}
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
@@ -20,21 +20,6 @@
));
}
- public function executeThumbTransform(
- PhabricatorFile $file,
- $x,
- $y) {
-
- $image = $this->crudelyScaleTo($file, $x, $y);
-
- return PhabricatorFile::newFromFileData(
- $image,
- array(
- 'name' => 'thumb-'.$file->getName(),
- 'canCDN' => true,
- ));
- }
-
public function executeProfileTransform(
PhabricatorFile $file,
$x,
@@ -123,21 +108,6 @@
return self::saveImageDataInAnyFormat($dst, $file->getMimeType());
}
-
- /**
- * Very crudely scale an image up or down to an exact size.
- */
- private function crudelyScaleTo(PhabricatorFile $file, $dx, $dy) {
- $scaled = $this->applyScaleWithImagemagick($file, $dx, $dy);
-
- if ($scaled != null) {
- return $scaled;
- }
-
- $dst = $this->applyScaleTo($file, $dx, $dy);
- return self::saveImageDataInAnyFormat($dst, $file->getMimeType());
- }
-
private function getBlankDestinationFile($dx, $dy) {
$dst = imagecreatetruecolor($dx, $dy);
imagesavealpha($dst, true);
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
@@ -44,50 +44,33 @@
}
}
- $type = $file->getMimeType();
-
- if (!$file->isViewableInBrowser() || !$file->isTransformableImage()) {
- return $this->buildDefaultTransformation($file, $transform);
+ $xforms = PhabricatorFileTransform::getAllTransforms();
+ if (!isset($xforms[$transform])) {
+ return new Aphront404Response();
}
+ $xform = $xforms[$transform];
+
// We're essentially just building a cache here and don't need CSRF
// protection.
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
$xformed_file = null;
-
- $xforms = PhabricatorFileTransform::getAllTransforms();
- if (isset($xforms[$transform])) {
- $xform = $xforms[$transform];
- if ($xform->canApplyTransform($file)) {
- try {
- $xformed_file = $xforms[$transform]->applyTransform($file);
- } catch (Exception $ex) {
- // In normal transform mode, we ignore failures and generate a
- // default transform below. If we're explicitly regenerating the
- // thumbnail, rethrow the exception.
- if ($is_regenerate) {
- throw $ex;
- }
+ if ($xform->canApplyTransform($file)) {
+ try {
+ $xformed_file = $xforms[$transform]->applyTransform($file);
+ } catch (Exception $ex) {
+ // In normal transform mode, we ignore failures and generate a
+ // default transform below. If we're explicitly regenerating the
+ // thumbnail, rethrow the exception.
+ if ($is_regenerate) {
+ throw $ex;
}
}
-
- if (!$xformed_file) {
- $xformed_file = $xform->getDefaultTransform($file);
- }
}
if (!$xformed_file) {
- switch ($transform) {
- case 'thumb-profile':
- $xformed_file = $this->executeThumbTransform($file, 50, 50);
- break;
- case 'thumb-280x210':
- $xformed_file = $this->executeThumbTransform($file, 280, 210);
- break;
- default:
- return new Aphront400Response();
- }
+ $xformed_file = $xform->getDefaultTransform($file);
}
if (!$xformed_file) {
@@ -103,40 +86,6 @@
return $this->buildTransformedFileResponse($xform);
}
- private function buildDefaultTransformation(
- PhabricatorFile $file,
- $transform) {
- static $regexps = array(
- '@application/zip@' => 'zip',
- '@image/@' => 'image',
- '@application/pdf@' => 'pdf',
- '@.*@' => 'default',
- );
-
- $type = $file->getMimeType();
- $prefix = 'default';
- foreach ($regexps as $regexp => $implied_prefix) {
- if (preg_match($regexp, $type)) {
- $prefix = $implied_prefix;
- break;
- }
- }
-
- switch ($transform) {
- case 'thumb-280x210':
- $suffix = '280x210';
- break;
- default:
- throw new Exception('Unsupported transformation type!');
- }
-
- $path = celerity_get_resource_uri(
- "rsrc/image/icon/fatcow/thumbnails/{$prefix}{$suffix}.png");
-
- return id(new AphrontRedirectResponse())
- ->setURI($path);
- }
-
private function buildTransformedFileResponse(
PhabricatorTransformedFile $xform) {
@@ -154,11 +103,6 @@
return $file->getRedirectResponse();
}
- private function executeThumbTransform(PhabricatorFile $file, $x, $y) {
- $xformer = new PhabricatorImageTransformer();
- return $xformer->executeThumbTransform($file, $x, $y);
- }
-
private function destroyTransform(PhabricatorTransformedFile $xform) {
$file = id(new PhabricatorFileQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
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
@@ -784,14 +784,6 @@
return PhabricatorEnv::getCDNURI($path);
}
- public function getProfileThumbURI() {
- return $this->getTransformedURI('thumb-profile');
- }
-
- public function getThumb280x210URI() {
- return $this->getTransformedURI('thumb-280x210');
- }
-
public function isViewableInBrowser() {
return ($this->getViewableMimeType() !== null);
}
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
@@ -42,13 +42,20 @@
$dst_w, $dst_h,
$src_x, $src_y,
$src_w, $src_h,
- $use_w, $use_h) {
+ $use_w, $use_h,
+ $scale_up) {
+
+ // Figure out the effective destination width, height, and offsets.
+ $cpy_w = min($dst_w, $use_w);
+ $cpy_h = min($dst_h, $use_h);
+
+ // If we aren't scaling up, and are copying a very small source image,
+ // we're just going to center it in the destination image.
+ if (!$scale_up) {
+ $cpy_w = min($cpy_w, $src_w);
+ $cpy_h = min($cpy_h, $src_h);
+ }
- // Figure out the effective destination width, height, and offsets. We
- // never want to scale images up, so if we're copying a very small source
- // image we're just going to center it in the destination image.
- $cpy_w = min($dst_w, $src_w, $use_w);
- $cpy_h = min($dst_h, $src_h, $use_h);
$off_x = ($dst_w - $cpy_w) / 2;
$off_y = ($dst_h - $cpy_h) / 2;
@@ -58,11 +65,18 @@
$argv[] = '-shave';
$argv[] = $src_x.'x'.$src_y;
$argv[] = '-resize';
- $argv[] = $dst_w.'x'.$dst_h.'>';
+
+ if ($scale_up) {
+ $argv[] = $dst_w.'x'.$dst_h;
+ } else {
+ $argv[] = $dst_w.'x'.$dst_h.'>';
+ }
+
$argv[] = '-bordercolor';
$argv[] = 'rgba(255, 255, 255, 0)';
$argv[] = '-border';
$argv[] = $off_x.'x'.$off_y;
+
return $this->applyImagemagick($argv);
}
@@ -117,7 +131,13 @@
* @param string Raw file data.
*/
protected function newFileFromData($data) {
- $name = $this->getTransformKey().'-'.$this->file->getName();
+ if ($this->file) {
+ $name = $this->file->getName();
+ } else {
+ $name = 'default.png';
+ }
+
+ $name = $this->getTransformKey().'-'.$name;
return PhabricatorFile::newFromFileData(
$data,
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
@@ -12,6 +12,7 @@
private $key;
private $dstX;
private $dstY;
+ private $scaleUp;
public function setName($name) {
$this->name = $name;
@@ -29,6 +30,11 @@
return $this;
}
+ public function setScaleUp($scale) {
+ $this->scaleUp = $scale;
+ return $this;
+ }
+
public function getTransformName() {
return $this->name;
}
@@ -42,7 +48,8 @@
id(new PhabricatorFileThumbnailTransform())
->setName(pht("Profile (100px \xC3\x97 100px)"))
->setKey(self::TRANSFORM_PROFILE)
- ->setDimensions(100, 100),
+ ->setDimensions(100, 100)
+ ->setScaleUp(true),
id(new PhabricatorFileThumbnailTransform())
->setName(pht("Pinboard (280px \xC3\x97 210px)"))
->setKey(self::TRANSFORM_PINBOARD)
@@ -86,7 +93,8 @@
$copy_x,
$copy_y,
$use_x,
- $use_y);
+ $use_y,
+ $this->scaleUp);
}
@@ -144,22 +152,35 @@
$copy_x = $src_x;
$copy_y = $src_y;
} else {
+ $scale_up = $this->scaleUp;
+
// Otherwise, both dimensions are fixed. Figure out how much we'd have to
// scale the image down along each dimension to get the entire thing to
// fit.
- $scale_x = min(($dst_x / $src_x), 1);
- $scale_y = min(($dst_y / $src_y), 1);
+ $scale_x = ($dst_x / $src_x);
+ $scale_y = ($dst_y / $src_y);
+
+ if (!$scale_up) {
+ $scale_x = min($scale_x, 1);
+ $scale_y = min($scale_y, 1);
+ }
if ($scale_x > $scale_y) {
// This image is relatively tall and narrow. We're going to crop off the
// top and bottom.
- $copy_x = $src_x;
- $copy_y = min($src_y, $dst_y / $scale_x);
+ $scale = $scale_x;
} else {
// This image is relatively short and wide. We're going to crop off the
// left and right.
- $copy_x = min($src_x, $dst_x / $scale_y);
- $copy_y = $src_y;
+ $scale = $scale_y;
+ }
+
+ $copy_x = $dst_x / $scale_x;
+ $copy_y = $dst_y / $scale_x;
+
+ if (!$scale_up) {
+ $copy_x = min($src_x, $copy_x);
+ $copy_y = min($src_y, $copy_y);
}
// In this mode, we always use the entire destination image. We may
diff --git a/src/applications/macro/query/PhabricatorMacroSearchEngine.php b/src/applications/macro/query/PhabricatorMacroSearchEngine.php
--- a/src/applications/macro/query/PhabricatorMacroSearchEngine.php
+++ b/src/applications/macro/query/PhabricatorMacroSearchEngine.php
@@ -179,14 +179,18 @@
assert_instances_of($macros, 'PhabricatorFileImageMacro');
$viewer = $this->requireViewer();
+ $xform = PhabricatorFileTransform::getTransformByKey(
+ PhabricatorFileThumbnailTransform::TRANSFORM_PINBOARD);
+
$pinboard = new PHUIPinboardView();
foreach ($macros as $macro) {
$file = $macro->getFile();
$item = new PHUIPinboardItemView();
if ($file) {
- $item->setImageURI($file->getThumb280x210URI());
- $item->setImageSize(280, 210);
+ $item->setImageURI($file->getURIForTransform($xform));
+ list($x, $y) = $xform->getTransformedDimensions($file);
+ $item->setImageSize($x, $y);
}
if ($macro->getDateCreated()) {
diff --git a/src/applications/pholio/query/PholioMockSearchEngine.php b/src/applications/pholio/query/PholioMockSearchEngine.php
--- a/src/applications/pholio/query/PholioMockSearchEngine.php
+++ b/src/applications/pholio/query/PholioMockSearchEngine.php
@@ -141,15 +141,22 @@
$viewer = $this->requireViewer();
+ $xform = PhabricatorFileTransform::getTransformByKey(
+ PhabricatorFileThumbnailTransform::TRANSFORM_PINBOARD);
+
$board = new PHUIPinboardView();
foreach ($mocks as $mock) {
+ $image = $mock->getCoverFile();
+ $image_uri = $image->getURIForTransform($xform);
+ list($x, $y) = $xform->getTransformedDimensions($image);
+
$header = 'M'.$mock->getID().' '.$mock->getName();
$item = id(new PHUIPinboardItemView())
->setHeader($header)
->setURI('/M'.$mock->getID())
- ->setImageURI($mock->getCoverFile()->getThumb280x210URI())
- ->setImageSize(280, 210)
+ ->setImageURI($image_uri)
+ ->setImageSize($x, $y)
->setDisabled($mock->isClosed())
->addIconCount('fa-picture-o', count($mock->getImages()))
->addIconCount('fa-trophy', $mock->getTokenCount());
diff --git a/src/applications/pholio/view/PholioMockEmbedView.php b/src/applications/pholio/view/PholioMockEmbedView.php
--- a/src/applications/pholio/view/PholioMockEmbedView.php
+++ b/src/applications/pholio/view/PholioMockEmbedView.php
@@ -28,25 +28,29 @@
$this->mock->getImages(), array_flip($this->images));
}
+ $xform = PhabricatorFileTransform::getTransformByKey(
+ PhabricatorFileThumbnailTransform::TRANSFORM_PINBOARD);
+
if ($images_to_show) {
- foreach ($images_to_show as $image) {
- $thumbfile = $image->getFile();
- $thumbnail = $thumbfile->getThumb280x210URI();
- }
+ $image = head($images_to_show);
+ $thumbfile = $image->getFile();
$header = 'M'.$mock->getID().' '.$mock->getName().
' (#'.$image->getID().')';
$uri = '/M'.$this->mock->getID().'/'.$image->getID().'/';
} else {
- $thumbnail = $mock->getCoverFile()->getThumb280x210URI();
+ $thumbfile = $mock->getCoverFile();
$header = 'M'.$mock->getID().' '.$mock->getName();
$uri = '/M'.$this->mock->getID();
}
+ $thumbnail = $thumbfile->getURIForTransform($xform);
+ list($x, $y) = $xform->getTransformedDimensions($thumbfile);
+
$item = id(new PHUIPinboardItemView())
->setHeader($header)
->setURI($uri)
->setImageURI($thumbnail)
- ->setImageSize(280, 210)
+ ->setImageSize($x, $y)
->setDisabled($mock->isClosed())
->addIconCount('fa-picture-o', count($mock->getImages()))
->addIconCount('fa-trophy', $mock->getTokenCount());
diff --git a/src/applications/pholio/view/PholioMockImagesView.php b/src/applications/pholio/view/PholioMockImagesView.php
--- a/src/applications/pholio/view/PholioMockImagesView.php
+++ b/src/applications/pholio/view/PholioMockImagesView.php
@@ -68,8 +68,11 @@
// TODO: We could maybe do a better job with tailoring this, which is the
// image shown on the review stage.
- $nonimage_uri = celerity_get_resource_uri(
- 'rsrc/image/icon/fatcow/thumbnails/default.p100.png');
+ $default_name = 'image-100x100.png';
+ $builtins = PhabricatorFile::loadBuiltins(
+ $this->getUser(),
+ array($default_name));
+ $default = $builtins[$default_name];
$engine = id(new PhabricatorMarkupEngine())
->setViewer($this->getUser());
@@ -97,7 +100,7 @@
'fullURI' => $file->getBestURI(),
'stageURI' => ($file->isViewableImage()
? $file->getBestURI()
- : $nonimage_uri),
+ : $default->getBestURI()),
'pageURI' => $this->getImagePageURI($image, $mock),
'downloadURI' => $file->getDownloadURI(),
'historyURI' => $history_uri,
diff --git a/src/applications/pholio/view/PholioUploadedImageView.php b/src/applications/pholio/view/PholioUploadedImageView.php
--- a/src/applications/pholio/view/PholioUploadedImageView.php
+++ b/src/applications/pholio/view/PholioUploadedImageView.php
@@ -38,11 +38,15 @@
->setSigil('image-description')
->setLabel(pht('Description'));
+ $xform = PhabricatorFileTransform::getTransformByKey(
+ PhabricatorFileThumbnailTransform::TRANSFORM_PINBOARD);
+ $thumbnail_uri = $file->getURIForTransform($xform);
+
$thumb_frame = phutil_tag(
'div',
array(
'class' => 'pholio-thumb-frame',
- 'style' => 'background-image: url('.$file->getThumb280x210URI().');',
+ 'style' => 'background-image: url('.$thumbnail_uri.');',
));
$handle = javelin_tag(
diff --git a/webroot/rsrc/css/application/auth/auth.css b/webroot/rsrc/css/application/auth/auth.css
--- a/webroot/rsrc/css/application/auth/auth.css
+++ b/webroot/rsrc/css/application/auth/auth.css
@@ -28,6 +28,7 @@
border: 1px solid {$lightblueborder};
background-repeat: no-repeat;
background-position: 4px 4px;
+ background-size: 50px 50px;
padding: 4px 4px 4px 62px;
min-height: 50px;
border-radius: 2px;
diff --git a/webroot/rsrc/image/icon/fatcow/thumbnails/default280x210.png b/webroot/rsrc/image/icon/fatcow/thumbnails/default280x210.png
deleted file mode 100644
index 7288c81954ec6a5e5916cdbbe6c93c2eb660390e..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
literal 2123
zc%17D@N?(olHy`uVBq!ia0y~yV3Yu|FLAH|$%$R}UjZq}64!{5;QX|b^2DN42FH~A
zq*MjZ+{E<Mpwz^a%EFVWHVh2RDw!b>B@w<pR>}FfdWj%4dKI|^3?N`*Ur~^loSj;t
zkd&I9nP;o?e)oPQh0GLNrEpVU1K$GY)Qn7zs-o23D!-8As_bOT6eW8*1)B;hpaHq5
zC5Z|ZxjA{oRu#5NU~{d2Y>=?Nk^)#sNw%#L#8DBx0SeCfMX3s=dd9lR28M<TW@dVZ
zCZ=X)hB^vH28KrZ20&z{YiMF+YG!3*t^fr}K--E^(yW49+@N*=dA3R!B_#z``ugSN
z<$C4Ddih1^`i7R4mLM~XjC6r2bc-wVN)jt{^NN*WCb*;)Cl_TFlw{`TDS-HiN%^HE
zwn|DcFXR@$jm;~D1`{yA^eYkz^bPe4^pO<$`r=obn+sQ6ToRO;hF^7YNM%8)eo$(0
zerZuMFyhjbL7EG!oQqNuOY)0C^7C_Gp%{>nUy@&(kzb(T9Bihb;hUJ8nFkWk1ncni
zwerj>E=kNwPW5!LRRW6WWoD*WIh#8<nHiayxH>yI8XCG9TUa<bJ3AT}7`hl6IGdW8
z!1TK0Czs}?=9R$orXcj1;?xUD3=rL^MVV!(DQ-pixe8!UTV>*QixF<OK=h{Ic8f7i
zz4}1M=%Yn7ObD2MKumbT1#;j?KQ#}S-iv?<d-DU9?+gqqdp%toLn>~)x$B!B5-M}x
zVez{?H#k{dIx(?`Z4!*#Sj_lFHN&g&=IX-Sh?7mNit9>ViYMeJ>#7{<tz*48t3ff5
z+3=H^F3YPkPv`73-fHCgVoAB!6FdLn%OcCRpL}^%|G#m5Z)zl4L!^cdqk=)h0R|2p
z@+k%;W{N4GQ4~{P2jwr?rkb%%BDwni)cN7_zCC{VwQlCWrE`ACtW|2ulZdJQa8~{K
z<>~+PN@s7<(cO07g2P^!>BqzU-o8-TfA?2);=`k#__OcN+dE<3o9Hl>ww!gdVw`sT
zJHA(7^~z^k?@v*m<oIh(K}mf_{6C3P@6Wd`J@2P8PkZ|Gd9~_Be~#B0@ZMML-R`=!
zM788n+48-;i+A1q!KHQR?C;eNuT;NZazZBlP3_h_Q~c921trW%f;4Wel$sk>^VV=r
zY+#N`*83RqJ3D?`%(2_$pCTZkw)N7rj9bY$`>y-BoBy%vI`iqdx>$LvkR;2pkH`Ao
zZ@H8*NnUW)vlV^;%iabF^1ZFpmbrJ?`}WeU9|CXb#r}Tu<k6p}Q>Q+t+voQA^zvN-
zms}>jf6#k-M{eJxiiV$GeoPe5|0iO$&+z~A1cN<~%lE#hnX~WJ(#M^mViL3VxN2>a
zpOG^muj2W|%LQK#ZG5<K>c0dF`Lmoo2QGX$aO5RZ@RHm2qHE>e*;U%ji8EuHadF=3
z!-qdVejC1J7nAd2^%+S!-p*XdR`_V={&`!w4;WM`Zb{O8?3S6}m~bPjJH$W1A)(@{
zlg6sIezJ{*hZPKbd<>YH4+N~gIB!|#nRj<Mc+@1i8x9yO=3dybl~*RH^?-rlK@J|K
z!#R2_VS%=u>)NU-7rzx_I-GV_X2yd+6_z%u-mDL==hySb$A`2#&T2VVR}hdXAW^%L
z=l<i=FHOf~eGN4AYS$OJB>bq)I3`~@hm)o4>}2<U8s&E7PdJx-;jsqtrDw`auj5_c
zx{m4dD>k0Sg%hn7Z_l*&{I7B5oZmB5fx(g;ZoOvT->>?+uYbNBeeG*n;KpCKJ%8T$
zAMq&d{PBB@YYy)JBk_Hi|NCXhb!@+9)+E~c9DiHVYrE+dlk;b$%O{<Etacgy64bx6
zaoW0#rK@!f7`A?Dzs}Ie$in83KmjEnK{>_3Mll6;P=)edkpu=6rK8?jdp8Gws&`LU
KKbLh*2~7Ze$@y0R
diff --git a/webroot/rsrc/image/icon/fatcow/thumbnails/image280x210.png b/webroot/rsrc/image/icon/fatcow/thumbnails/image280x210.png
deleted file mode 100644
index efdf733f8eeb118cb36403c6cb9a741d0ded879f..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
literal 2600
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
diff --git a/webroot/rsrc/image/icon/fatcow/thumbnails/pdf280x210.png b/webroot/rsrc/image/icon/fatcow/thumbnails/pdf280x210.png
deleted file mode 100644
index 8036981aca18575e4fed1ebfa343188e5fed852c..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
literal 2824
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
diff --git a/webroot/rsrc/image/icon/fatcow/thumbnails/zip280x210.png b/webroot/rsrc/image/icon/fatcow/thumbnails/zip280x210.png
deleted file mode 100644
index 8db127b282c1ea95127548ba0022eabd8475315a..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
literal 2511
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
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Mar 19, 2:10 AM (5 d, 14 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7312669
Default Alt Text
D12818.id30808.diff (29 KB)
Attached To
Mode
D12818: Convert "profile" image transforms to the new pathway
Attached
Detach File
Event Timeline
Log In to Comment