Skip to main content

Shop Solution for Plone

Project description

E-commerce solution for Plone

https://github.com/bluedynamics/bda.plone.shop/actions/workflows/main.yml/badge.svg https://black.readthedocs.io/en/stable/_static/pypi.svg

Installation

Depend your instance to bda.plone.shop and install it as addon in plone control panel.

Development and testing

Checkout bda.plone.shop from git://github.com/bluedynamics/bda.plone.shop.git and run:

~$ make install

This installs all dependencies with mxdev and prepares scripts for running tests.

Running tests

If you have run the buildout, you can run all tests like so:

~$ make test-ignore-warnings

To run the robot tests do:

./venv/bin/zope-testrunner --auto-color --auto-progress --test-path=./src --all

For development, it might be more convenient to start a test server and run robot tests individually, like so (-d to start Zope in DEBUG-MODE):

./venv/bin/robot-server bda.plone.shop.tests.ShopDXFull_ROBOT_TESTING -d
./venv/bin/robot src/bda/plone/shop/tests/robot/test_shop_orderprocess.robot

To automatically land in the debug shell on test-failure, use:

./venv/bin/robot-debug src/bda/plone/shop/tests/robot/test_shop_orderprocess.robot

In the robot test you can place the debug statement to access a robot shell to try things out.

For more information on this topic visit: https://docs.plone.org/external/plone.app.robotframework/docs/source/happy.html

Enable Content to be buyable

Content which represent buyable items must implement bda.plone.orders.interfaces.IBuyable.

Information related to Buyable items is acquired from content instance via adapters implementing the following interfaces:

- ``bda.plone.cart.interfaces.ICartItemDataProvider``
- ``bda.plone.cart.interfaces.ICartItemStock``
- ``bda.plone.shipping.interfaces.IShippingItem``
- ``bda.plone.orders.interfaces.IItemNotificationText``
- ``bda.plone.orders.interfaces.IGlobalNotificationText``
- ``bda.plone.orders.interfaces.ITrading``
- ``bda.plone.orders.interfaces.IBuyablePeriod``

There exists implementations of these adapters among with related Dexterity Behaviors.

For Plone 5 ‘Summary View’ is overriden for folders and collections to show your buyables with controls to add them into the cart.

Dexterity

The Dexterity related implementation consists of Behaviors for each interface. These are (shortname in brackets):

  • bda.plone.shop.dx.IBuyableBehavior (bda.shop.buyable)

  • bda.plone.shop.dx.IStockBehavior (bda.shop.stock)

  • bda.plone.shop.dx.IShippingBehavior (bda.shop.shipping)

  • bda.plone.shop.dx.IItemNotificationTextBehavior (bda.shop.notificationtext.item)

  • bda.plone.shop.dx.IGlobalNotificationTextBehavior (bda.shop.notificationtext.global)

  • bda.plone.shop.dx.ITradingBehavior (bda.shop.trading)

  • bda.plone.shop.dx.IBuyablePeriodBehavior (bda.shop.buyableperiod)

The corresponding adapter implementations are registered for the referring behavior interfaces.

The IBuyable interface gets hooked on content via IBuyableBehavior.

In order to create buyable items with dexterity you need to either create a portal type via GenericSetup or use the Dexterity TTW Editor to assign the behaviors to existing content, or create new type(s) TTW from scratch.

Notification related behaviors can be applied to any Dexterity object including buyable items, notification text values are aquired until plone root is reached.

Cart item preview images

The cart can render preview images for the cart items in case when the context has a field named image

You can change the preview image rendering by adapting your own cart items. If you want to change the scale of the image, inherit from the existing adapter class and change preview_scale property:

>>> from bda.plone.shop.dx import DXCartItemPreviewImage
>>> class MyDXCartItemPreviewImage(DXCartItemPreviewImage):
...     preview_scale = "my_scale"

To do more complex preview image rendering you can override the url property:

>>> class MyDXCartItemPreviewImage(DXCartItemPreviewImage):
...     @property
...     def url(self):
...         # do sophisticated stuff to get your preview image
...         return preview_url

Register your adapter via ZCML:

<adapter
  for="some.package.IMyDXContent"
  factory=".youradater.MyDXCartItemPreviewImage" />

Permissions

In general, custom shop deployments are likely to configure the permission and role settings according to their use cases.

There exists bda.plone.shop.ViewBuyableInfo and bda.plone.shop.ModifyCart permission to control what parts of buyable data and controls get exposed to the user.

Further the permissions bda.plone.shop.ChangePersonalInformation and bda.plone.shop.ChangePersonalPreferences are used to control access to Personal Preferences respective Personal Information pages. By default, users with role Customer can access Personal Information only, as it usually makes no sense to give a customer settings like a preferred editor.

bda.plone.shop.ViewBuyableInfo

This permission controls whether a user can view basic buyable information. These are item availability and item price. By default, this permission is set for roles:

  • Manager

  • Site Administrator

  • Reviewer

  • Editor

  • Customer

  • Authenticated

This permission is also granted to the Authenticated role, to cover the use case, where authenticated users should see price informations, but not buy items.

In order to expose buyable information to all visitors by default, add Anonymous role via generic setup’s rolemap.xml of your integration package.

bda.plone.shop.ModifyCart

This permission controls whether a user can actually add or update this item to shopping cart. By default, this permission is set for roles:

  • Manager

  • Site Administrator

  • Customer

In order to enable non-customers or anonymous users to mofify the cart, edit rolemap.xml in your integration package as needed. Be aware that the shop is basically designed that anonymous users can buy items, but orders related features like viewing own orders are bound to Customer role.

Customizing the shop

We know that every web-shop has different needs. This is why bda.plone.shop has been designed with maximum flexibility in mind.

In general, bda.plone.shop is customized by either changing settings in the (always growing) control-panel, or by patching variables/classes.

Integrators might want to add a patchShop method to the initialize method of a Zope2 package:

def initialize(context):
    """Initializer called when used as a Zope 2 product.
    """
    patchShop()

…and make sure it’s called at startup time using the zcml:

<configure
  xmlns="http://namespaces.zope.org/zope"
  xmlns:five="http://namespaces.zope.org/five">

  <five:registerPackage package="." initialize=".initialize" />

</configure>

In patchShop you typically import constants from bda.plone.shop related packages and redefine them.:

def patchShop():
    from bda.plone import cart
    cart.CURRENCY_LITERALS['EUR'] = u'€'

Please see bda.plone.checkout or bda.plone.order for information how to customize the checkout form or the notification emails respectively.

Troubleshooting

If you’re missing widgets in the @@item_discount form (eg. the Autocomplete for users or groups), you might want to reinstall (or re-run the GS import steps) of the yafowil.plone (see its README for more information).

If the autocomplete widget (in @@item_discount) is not working you can try to disable ++resource++yafowil.widget.autocomplete/jquery-ui-1.8.18.autocomplete.min.js in portal_javascripts.

In case you’re having trouble with the forms, check if you’re having recent versions of yafowil >= 2.1 and yafowil related packages.

Create translations

$ cd src/bda/plone/shop/
$ ./i18n.sh

Backward incompatible changes

1.0a1

  • bda.plone.shop: Buy Items permission has been renamed to bda.plone.shop: Modify Cart. If you have custom rolemap.xml in your GS profiles using this permission, or you use this permission somewhere in your code, you need to update your customizations.

Upgrade to Plone 5

If you upgrade to Plone 5, you have to run the upgrade step Remove old JS and CSS resources for Plone 5 manually to remove the old registration of resources.

Contributors

We’d be happy to see forks and pull-requests to improve this program. Professional support is offered by the maintainers and some of the authors.

Maintainers

  • Robert Niederreiter

  • Peter Holzer

  • Jens Klein

Contact: dev@bluedynamics.com

Authors

  • Robert Niederreiter (initial Author)

  • Peter Holzer

  • Peter Mathis

  • Harald Frießnegger

  • Espen Moe-Nilssen

  • Johannes Raggam

  • Jure Cerjak

  • Benjamin Stefaner

  • Jens Klein

Changelog

2.0b1 (2024-04-17)

  • Introduce bda.plone.shop.cartdata.CHECKOUT_INTERMEDIATE_VIEW. [rnix]

  • Remove Archetypes related documentation. [rnix]

  • Use BooleanIndex for item_buyable & add metadata. [agitator]

  • Use Decimal for shipping and article defaults. [agitator]

  • Fix availability details pop-up [petri]

  • Refactor buyable.[py|pt] for localized number output and better Decimal usage. Also use Python expressions for performance. [jensens]

  • Use Decimal field for net price and cast to Decimal (for old values) in accessor. [jensens]

  • provide information wether a comment is enabled or not on cartitem data. [jensens]

  • Take buyable period for availability signal into account. [jensens]

  • Mark buyable dl if comments are enabled or not to ease styling. [jensens]

  • Localized number input for count. [jensens]

  • No longer support for z3c.autoinclude. [jensens]

  • Add more available units. [jensens]

  • Make invoice fields optional [agitator]

  • Code style black. [jensens]

  • Fix import for latest cart/shipping changes. [jensens]

  • Python 2/3 compatibility [agitator]

  • Update version and classifiers - 2.x targets Plone 5.1/5.2 without Archetypes [agitator]

  • Italian translations [ale-rt]

  • migration: fixed an edgecase when upgrading old shop installations [petschki]

1.0a1 (unreleased)

  • Replace unittest2 with unittest [llisa123]

  • Use userschema.xml to extend shop specific user data for Plone 5. [agitator]

  • Add invoice settings. [rnix]

  • Some CSS fixes for shop settings in plone 5. [rnix]

  • Fix failing bin/instance adduser in Plone due to not initialized registry on startup. Fixes: #100. [thet]

  • Add metadata columns for item_net, item_buyable_start and item_buyable_end. This way, they can be displayed in the table view of collection results. [thet]

  • Hide empty toolbar categories [agitator]

  • Deliver discount in cart item data. [rnix]

  • Rename bda.plone.shop: Buy Items permission to bda.plone.shop: Modify Cart. [rnix]

  • Added buyable_controls to summary_view via override of plone.app.contentypes [agitator]

  • Use ICartDataProvider adapter lookup instead of CartItemCalculator directly in shipping calculation to ensure possible custom implementation to take effect. [rnix]

  • Deprecate use of bda.plone.shop.cartdata.CartItemCalculator. [rnix]

  • Fix error if item from cart cookie not found. [rnix]

  • Fix display of currency in buyable viewlet based on shop settings [agitator]

  • Implement IShippingItem.free_shipping for AT and DX. Consider this flag in conjunction with item shipping costs in DefaultShipping. [rnix]

  • Do not add shop admin portlet assignment on install in Plone 5 [rnix]

  • Implement shop navigation menu for Plone 5 toolbar. [rnix]

  • Move shop portlet related link implementations to bda.plone.shop.browser.navigation. [rnix]

  • use MwSt. instead of Ust. in german [agitator]

  • Overhaul code: use plone.api and zca decorators [jensens]

  • Fix: Do not raise AttributeError if admin email or name were not yet set. [jensens]

  • Add upgrade step for default_item_stock_warning_threshold setting. [thet]

  • Add default_item_stock_warning_threshold setting for default_item_minimum_stock property from bda.plone.orders. [andreesg]

  • Behavior registration: Remove superfluos ‘for’ and give behaviors short names. [jensens]

  • Add a PlonePAS Plugin for computed user properties. [pcdummy]

  • Plone 5 Update, use separate styles/less. [agitator]

  • Shop Portlet: Use appropriate context (Vendor, Site or Plone Site Root) also for Orders and Bookings views. [thet]

  • Shop Portlet: Use appropriate context for “orders in context”, like it’s done for “bookings in context”. Avoids calling this view on default pages. [thet]

  • Shop Portlet: Add Shop Controlpanel admin link, linking to ISite or IPloneSiteRoot. If lineage.registry is installed, the shop settings can also be set on subsite level. [thet]

  • Always show the mailtemplate link in the shop portlet, but link to the correct context. Rename i18n messages to reflect, if context is on a IVendor object (vendor), on a ISite (site-wide) or on a IPloneSiteRoot (global). [thet]

  • Resolve JSHint errors and warnings. [thet]

  • Fix: buyable_period was started one minute after the given time. [jensens]

  • Separate AT and DX zcml registrations into own files for a better overview. [thet]

  • Disable adapter for deprecated FlatRate shipping. [jensens]

  • Change imports of IBuyable to bda.plone.orders - get rid of deprecation messages [jensens]

  • Added two views to the admin portlet in which bookings are displayed and can be grouped by the buyers email adress or the buyable uid. Both views support daterange filtering and text index support. The Bookings view gets called on the portal root and the Bookings in Context returns all bookings data on the corresponding context it is called. [benniboy]

  • Moved IBuyable to bda.plone.orders to avoid circular dependencies. [benniboy]

  • Consider buyable effective and expires dates in availability details and display appropriate messages. [rnix]

  • Change userdata adapters to named adapters, so other adapters can additionally extend the functionality. [thet]

  • Added default_item_cart_count_limit to control panel defaults. Don’t forget to run the update step. [agitator]

  • Display status messages when modifying cart data via buyable viewlet [rnix]

  • Add swiss VAT rates [rnix]

  • Do not show ‘Export Orders on this Item’ on Plone Site Root [jensens]

  • Use Products.statusmessages for displaying portal status messages when enabling or disabling Buyable or Vendor features. [thet]

0.9

  • Add “Cash and Carry” shipping. [rnix]

  • To enable and disable features on contexts (like vendor areas), don’t use directlyProvides and erase all other directly provided interfaces, but use alsoProvides. That’s needed for collective.lineage sites to work after a vendor area was activated on them. [thet]

0.8

  • Protect the @@myorders link in portlets.ShopAdmin portlet with the bda.plone.orders.ViewOwnOrders permission. [thet]

  • Remove validation constraint for “Accept terms and conditions” flag in user information. The validation only applies at checkout time. [rnix]

  • Do not fail in CashOnDeliverySettings.costs if IPaymentTextSettings.cash_on_delivery_costs not present yet. [rnix]

  • Introduce bda.plone.shop.utils.format_amount. [rnix]

  • Add IPaymentTextSettings.cash_on_delivery_costs setting. [rnix]

  • Add cash_in_advance and cash_on_delivery values to IPaymentTextSettings.available_payment_methods. [rnix]

  • Format currency values in default shipping messages. [rnix]

0.7

  • Skip Shop portlet entirely if no shop links for user available. [rnix]

  • Check for bda.plone.orders.ExportOrders permission in ShopPortletExportOrdersLink and ShopPortletExportOrdersItemLink. [rnix]

  • Bind dashboard user action to bda.plone.shop.ChangePersonalPreferences permission. [rnix]

  • Format actions.xml to make action translations work properly. GS Profile application required. [rnix]

  • Introcuce IShopSettings.add_customer_role_to_new_users and consider in principal created event subscriber. [rnix]

  • Introduce “Personal Information” user action and adopt “Personal Preferences” user action in order to get displayed for permitted users only. [rnix]

  • Introduce bda.plone.shop.ChangePersonalInformation and bda.plone.shop.ChangePersonalPreferences permissions and bind personal-preferences and personal-information views to shop layer and these permissions. [rnix]

  • Check whether shipping method stored on cookie is available (any longer). [rnix]

  • Implement bda.plone.orders.interfaces.ITrading for DX and AT. [rnix]

  • Register mailnotify.RegistryPaymentText for zope.component.interfaces.ISite instead of Products.CMFCore.interfaces.ISiteRoot. [rnix]

  • Check against order total value instead of payment method in CheckoutSettings.skip_payment. [rnix]

  • Add cartdata.CartDataProvider.max_artice_count. [rnix]

  • Remove cartdata.CartDataProvider.include_shipping_costs, it’s implemented now on base class. [rnix]

  • Remove IShopShippingSettings.include_shipping_costs, flag gets calculated now from IShippingItem.shippable. Note - Do not forget to run GS upgrade step 4 to 5 and adopt your integration package SG profile if necessary. [rnix]

  • Introduce IShopShippingSettings.default_shipping_item_shippable and use as default for IShippingItem.shippable. [rnix]

  • Implement bda.plone.shipping.interfaces.IShippingItem.shippable and consider at appropriate places. [rnix]

  • Implement bda.plone.checkout.interfaces.ICheckoutSettings at bda.plone.shop.checkout.CheckoutSettings. [rnix]

  • Implement bda.plone.shipping.interfaces.IShippingSettings at bda.plone.shop.shipping.ShippingSettings using bda.plone.shop.interfaces.IShopShippingSettings controlpanel settings. [rnix]

  • Implement bda.plone.payment.interfaces.IPaymentSettings at bda.plone.shop.payment.PaymentSettings using bda.plone.shop.interfaces.IPaymentTextSettings controlpanel settings. [rnix]

  • Add available_payment_methods, payment_method and skip_payment_if_order_contains_reservations to bda.plone.shop.interfaces.IPaymentTextSettings and provide GS upgrade step. [rnix]

  • Rename bda.plone.shop.vocabularies.PaymentVocabulary to bda.plone.shop.vocabularies.PaymentMethodsVocabulary. [rnix]

  • Implement bda.plone.orders.interfaces.IPaymentText at bda.plone.shop.mailnotify.RegistryPaymentText. [rnix]

  • Add admin portlet link for @@exportorders_contextual to export orders on this item. [thet]

  • Implement bda.plone.orders.interfaces.INotificationSettings in bda.plone.shop.mailnotify. [rnix]

  • Rename bda.plone.shop.notificationtext to bda.plone.shop.mailnotify. [rnix]

  • Add Shop Admin Name to control panel setting. [fRiSi]

  • Consider shipping method from cookie in cart data provider if present. [rnix]

  • Extend CartItemCalculator by item_net, item_vat and item_weight functions. [rnix]

  • Add DefaultShipping and corresponding control panel settings. GS upgrade 2_to_3 must be applied. [rnix]

  • Deprecate FlatRate shipping. [rnix]

  • Adopt shipping implementation to bda.plone.shipping >= 0.4. [rnix]

  • Fix displaying of discounted price. Original price only gets displayed if it deferrs from discounted one. [rnix]

  • Add documentation for customizing and installation. [fRiSi]

0.6

  • Display original price and discounted price in buyable controls if discount for item applies. [rnix]

  • Let CartDataProvider get the cart items title via an ICartItemDataProvider accessor to allow customizations. This can be used to give more context on the cart item, e.g. for a buyable within another content item. [thet]

0.5

  • Introduce IBuyablePeriod interface, Implement for AT and DX and include checks in buyable controls and cart validation. [rnix]

  • Implement validate_set on cart data provider. [rnix]

  • Change browser view and adapter regitrations from IPloneSiteRoot to zope.component.interfaces.ISite. That’s needed for Lineage compatibility. [thet]

  • Integrate cart_count_limit property of cart item data interface. [rnix]

  • Integrate hide_cart_if_empty property of cart data interface. [rnix]

  • Implement display property of stock interface and consider it in buyable controls. [rnix]

  • Changed markup and styles for the buyable_controls template, which is used for the buyable viewlet. [thet]

  • Create a show_available property for buyable_controls. When set to True, as by default, the available information is shown for each buyable. This can be turned off in a customized buyable class for shared stock buyables. [thet]

  • Remove buyable viewlet class, as it did not have any customization in it. This should not break backwards compatibility. [thet]

  • Stick to AccessControl directly for checking buyable controls permissions. <SpecialUser 'Anonymous User'> instance returned by plone.api.user.get_current() not provides checkPermission function, which makes it useless.

  • Introduce bda.plone.shop.ViewBuyableInfo and bda.plone.shop.BuyItems permissions and consider in buyable controls. Now it can be controlled whether users can see item pricing and whether they can buy items. [rnix]

  • Don’t register bda.plone.shop.buyable viewlet for IBelowContentBody but only for IAboveContentBody to avoid displaying it twice. Integrators should register it differently if they want to display the viewlet somewhere else. [thet]

  • Integrate discount related stuff. [rnix]

  • Set bda.plone.orders.permissions.DelegateVendorRole permission for Site Administrator and Manager roles in bda.plone.shop.browser.actions.VendorAction. [rnix]

  • Refactor Shop portlet and introduce bda.plone.shop.browser.admin.IShopPortletLink which can be used to hook up links to the shop portlet. [rnix, thet]

  • Implement bda.plone.orders.IPaymentText [rnix, jensens]

  • Implement bda.plone.orders.I[Item|Global]NotificationText [rnix, jensens]

  • Allow portal member to store billing and delivery address information and use these as defaults for the checkout process. [thet]

  • Fix BrowserLayer order precedence. [thet]

0.4

  • Deprecate bda.plone.shop.extender and bda.plone.shop.behaviors. [rnix]

  • Obtain available shipping methods by listing registered adapters. [fRiSi]

  • Take number in account when calculating weight. [fRiSi]

0.3

  • Add weight calculation in bda.plone.shop.cartdata.CartItemCalculator. [rnix]

  • Display delivery_duration in availability details if defined. [rnix]

  • Consider quantity_unit_float in CartItemAvailability implementation. [rnix]

  • Implement bda.plone.shipping.IShippingItem for Dexterity and Archetypes. [rnix]

  • Add controlpanel icon. [rnix]

  • Set browserlayer for browser resources. [rnix]

0.2

  • Vocabulary and controlpanel improvements. [rnix]

  • Control panel now displays with several field sets. [hpeter]

  • Refactor control panel by splitting up to several configuration interfaces. [hpeter]

  • Add controlpanel. [espenmn]

  • Extend AT and DX implementations by stock related interfaces. [rnix]

  • Implement cart contracts for Dexterity and Archetypes. [rnix]

  • No longer set bda.plone.shop.interfaces.IPotentiallyBuyable on all archetypes objects by default. Must be done in integration package. [rnix]

  • Add adapter for cart item preview images. [petschki]

  • Allow the shop administration portlet in the left column too. (fixes #2) [fRiSi]

0.1

  • initial work [rnix]

License

Copyright (c) 2012-2023, BlueDynamics Alliance, Austria All rights reserved.

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.

  • Neither the name of the BlueDynamics Alliance nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY BlueDynamics Alliance 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 BlueDynamics Alliance 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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bda.plone.shop-2.0b1.tar.gz (135.0 kB view details)

Uploaded Source

Built Distribution

bda.plone.shop-2.0b1-py3-none-any.whl (154.3 kB view details)

Uploaded Python 3

File details

Details for the file bda.plone.shop-2.0b1.tar.gz.

File metadata

  • Download URL: bda.plone.shop-2.0b1.tar.gz
  • Upload date:
  • Size: 135.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.0.0 CPython/3.9.2

File hashes

Hashes for bda.plone.shop-2.0b1.tar.gz
Algorithm Hash digest
SHA256 8f10780146bfee8cda0fb5b8c7134659f6b2acd1f9cc53ec76db3d4ff25b8124
MD5 4210d141fb2dbe5a9cdede8f325f1597
BLAKE2b-256 0c485663372f8b045b8c1747baafbee5559bcf9076c10a4a18559bbf0e1e894b

See more details on using hashes here.

File details

Details for the file bda.plone.shop-2.0b1-py3-none-any.whl.

File metadata

File hashes

Hashes for bda.plone.shop-2.0b1-py3-none-any.whl
Algorithm Hash digest
SHA256 f0cccfcbbbe86d8945abaaf5ac6e54080378236f4ac6c5ed55ac098577ad4c1f
MD5 f017d77b8b01ee73bb1756f155a84e03
BLAKE2b-256 0fb50e1bd689b84d7692f9e2a9332f6373282e4b5a30145ea812837d1fd144dd

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page