123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740 |
- # -*- coding: utf-8 -*-
- import pytest
- import datetime
- import difflib
- import finoex
- import ioex.calcex
- import ioex.datetimeex
- import os
- import pytz
- yaml = pytest.importorskip('yaml')
- def get_figure_a():
- return ioex.calcex.Figure(12.3, u'km')
- def get_figure_b():
- return ioex.calcex.Figure(12300, u'米')
- def get_sum_a():
- return finoex.Sum(1.23, u'EUR')
- def get_sum_b():
- return finoex.Sum(20.45, u'€')
- def get_item_a(sub_items = False):
- item = finoex.Item(
- name = u'item a',
- price_brutto = get_sum_a(),
- )
- if sub_items:
- item.sub_items.append(get_item_b())
- return item
- def get_item_b():
- return finoex.Item(
- name = u'item β',
- price_brutto = get_sum_b(),
- )
- def get_service_a():
- return finoex.Service(
- duration = ioex.datetimeex.Duration(years = 2),
- ip_addresses = ['::1'],
- location = 'vienna',
- name = u'service',
- price_brutto = finoex.Sum(1.0, u'EUR'),
- state = 'success',
- )
- def get_hosting_service():
- return finoex.HostingService(
- duration = ioex.datetimeex.Duration(years = 2),
- ip_addresses = ['127.0.0.1', '::1'],
- location = 'vienna',
- name = u'virtual server',
- operating_system = 'debian 8',
- price_brutto = finoex.Sum(1.0, u'EUR'),
- state = 'running',
- )
- def get_cloud_mining():
- return finoex.CloudMining(
- hashrate = ioex.calcex.Figure(8, u'TH/s'),
- name = u'sha256 BTC',
- price_brutto = finoex.Sum(1.0, u'EUR'),
- )
- def get_service_b():
- return finoex.Service(
- name = u'service',
- price_brutto = finoex.Sum(1.0, u'EUR'),
- period = ioex.datetimeex.Period(
- start = datetime.datetime(2017, 4, 2, 10, 23),
- end = None,
- ),
- )
- def get_person_a():
- return finoex.Person(
- first_name = u'Fabian Peter',
- last_name = u'Hammerle',
- )
- def get_person_b():
- return finoex.Person(
- first_name = u'名字',
- last_name = u'贵姓',
- )
- def get_campaign_a():
- return finoex.Campaign(
- name = u'campaign a',
- founder = u'company',
- end = datetime.datetime(2016, 7, 23, 9, 23, 17, tzinfo = pytz.timezone('Europe/Vienna')),
- )
- def get_campaign_b():
- return finoex.Campaign(
- founder = u'company',
- name = u'campaign without end',
- website_url = u'http://campaign.com',
- )
- def get_pledge():
- return finoex.Pledge(
- campaign = get_campaign_a(),
- price_brutto = finoex.Sum(10.0, u'EUR'),
- reward = u'great',
- )
- def get_contribution():
- return finoex.Contribution(
- campaign = get_campaign_a(),
- price_brutto = finoex.Sum(10.0, u'EUR'),
- reward = u'product',
- )
- def get_article():
- return finoex.Article(
- access_option = 'download',
- authors = ['a', 'b'],
- depth = finoex.Distance(12.3, u'dm'),
- features = u'supergeil',
- height = finoex.Distance(123., u'cm'),
- maximum_load = ioex.calcex.Figure(40., u'kg'),
- name = u'article name',
- price_brutto = get_sum_a(),
- product_id = u'0815',
- quantity = 1,
- release_date = datetime.date(2017, 10, 24),
- reseller = u'seller',
- shipper = u'shipper',
- state = u'goood',
- width = finoex.Distance(1.23, u'm'),
- )
- def get_transportation(period=False):
- arrival_time = pytz.timezone('Europe/Vienna').localize(
- datetime.datetime(2016, 7, 24, 23, 47, 35)
- )
- if period:
- arrival_time = ioex.datetimeex.Period(
- start=arrival_time,
- end=arrival_time + datetime.timedelta(days=2),
- )
- return finoex.Transportation(
- name = u'ticket',
- price_brutto = get_sum_a(),
- departure_point = u'home',
- destination_point = u'city',
- distance = finoex.Distance(3.21, u'km'),
- passenger = get_person_a(),
- valid_from = datetime.datetime(2016, 7, 14, 13, 50, 4, 0, tzinfo = pytz.timezone('Europe/Vienna')),
- valid_until = datetime.datetime(2016, 7, 14, 18, 50, 4, 0, tzinfo = pytz.utc),
- ticket_url = u'https://www.example.com',
- estimated_arrival_time = ioex.datetimeex.Period(
- start = pytz.timezone('Europe/Vienna').localize(datetime.datetime(2016, 7, 24, 23, 47, 2)),
- end = pytz.utc.localize(datetime.datetime(2016, 7, 24, 23, 48, 5)),
- ),
- arrival_time=arrival_time,
- )
- def get_shipping():
- return finoex.Shipping(
- price_brutto = get_sum_a(),
- destination_point = u'home',
- tracking_number = 'LX123456789CN',
- )
- def get_taxi_ride():
- return finoex.TaxiRide(
- name = u'taxi ride',
- price_brutto = get_sum_a(),
- departure_point = u'home',
- destination_point = u'city',
- distance = finoex.Distance(3.21, u'km'),
- driver = u'driver',
- arrival_time = datetime.datetime(2016, 5, 2, 18, 10, tzinfo = pytz.timezone('Europe/Vienna')),
- departure_time = datetime.datetime(2016, 5, 2, 18, 25, tzinfo = pytz.timezone('Europe/Vienna')),
- )
- def get_discount_a():
- return finoex.Discount(
- name = u'discount a',
- amount = get_sum_a(),
- )
- def get_discount_b():
- return finoex.Discount(
- name = u'discount β',
- amount = get_sum_b(),
- )
- def get_discount_c():
- return finoex.Discount(
- amount = get_sum_b(),
- code = 'DISCΓ',
- name = u'discount c',
- )
- def get_order_a(items = True, discounts = True):
- order = finoex.Order(
- customer_id = u'customer',
- order_date = datetime.datetime(2016, 5, 8, 0, 18, 17),
- order_id = u'id',
- platform = u'platformπ',
- platform_view_url = 'http://i.dont.know',
- )
- if items:
- order.items.append(get_item_a())
- order.items.append(get_item_b())
- if discounts:
- order.discounts.append(get_discount_a())
- order.discounts.append(get_discount_b())
- return order
- def get_order_b():
- order = finoex.Order(
- platform = u'platformπ',
- order_id = u'order_b',
- order_date = datetime.datetime(2015, 5, 8, 0, 18, 17),
- )
- return order
- def get_order_c():
- order = finoex.Order(
- platform = u'γάμμα',
- order_id = u'order_βήτα',
- order_date = datetime.datetime(2014, 5, 8, 0, 18, 17),
- customer_id = u'ρώ',
- )
- return order
- def get_invoice(items = True, discounts = True):
- inv = finoex.Invoice(
- creditor = u'platformπ',
- debitor_id = u'customer',
- invoice_date = datetime.datetime(2016, 5, 8, 0, 18, 17),
- invoice_id = u'id',
- invoice_url = 'http://example.com/invoice.pdf',
- )
- if items:
- inv.items.append(get_item_a())
- inv.items.append(get_item_b())
- if discounts:
- inv.discounts.append(get_discount_a())
- return inv
- def get_distance():
- return finoex.Distance(2.4142, u'km')
- def to_yaml(data):
- class Dumper(yaml.Dumper):
- pass
- ioex.datetimeex.Duration.register_yaml_representer(yaml.Dumper)
- ioex.datetimeex.Period.register_yaml_representer(yaml.Dumper)
- ioex.calcex.Figure.register_yaml_representer(yaml.Dumper)
- finoex.Sum.register_yaml_representer(yaml.Dumper)
- finoex.Distance.register_yaml_representer(yaml.Dumper)
- return yaml.dump(
- data,
- default_flow_style = False,
- allow_unicode = True,
- Dumper = Dumper,
- ) #.decode('utf-8')
- def yaml_diff(a, b):
- return '\n'.join(difflib.ndiff(
- to_yaml(a).split('\n'),
- to_yaml(b).split('\n'),
- ))
- @pytest.mark.parametrize('source_object,expected_yaml', [
- [datetime.datetime(2016, 7, 14, 13, 50, 4, 0), '2016-07-14 13:50:04\n...\n'],
- [datetime.datetime(2016, 7, 14, 13, 50, 4, 0, tzinfo = pytz.timezone('Europe/Vienna')), '2016-07-14 13:50:04+01:05\n...\n'],
- [datetime.datetime(2016, 7, 14, 13, 50, 4, 0, tzinfo = pytz.utc), '2016-07-14 13:50:04+00:00\n...\n'],
- [finoex.Distance(1.34, u'km'), u"!distance '1.34 km'\n"],
- [finoex.Distance(1.34, u'μm'), u"!distance '1.34 μm'\n"],
- [get_discount_a(), u"!discount\namount: !sum '1.23 EUR'\nname: discount a\n"],
- [get_discount_b(), u"!discount\namount: !sum '20.45 EUR'\nname: discount β\n"],
- [get_discount_c(), u"""!discount
- amount: !sum '20.45 EUR'
- code: DISCΓ
- name: discount c
- """],
- [get_figure_a(), u"!figure '12.3 km'\n"],
- [get_figure_b(), u"!figure '12300 米'\n"],
- [get_item_a(), u"!item\nname: item a\nprice_brutto: !sum '1.23 EUR'\n"],
- [get_item_a(sub_items=True), u"""!item
- name: item a
- price_brutto: !sum '1.23 EUR'
- sub_items:
- - !item
- name: item β
- price_brutto: !sum '20.45 EUR'
- """],
- [get_item_b(), u"!item\nname: item β\nprice_brutto: !sum '20.45 EUR'\n"],
- [get_person_a(), u'!person\nfirst_name: Fabian Peter\nlast_name: Hammerle\n'],
- [get_person_b(), u'!person\nfirst_name: 名字\nlast_name: 贵姓\n'],
- [get_campaign_a(), u"""!campaign
- end: 2016-07-23 09:23:17+01:05
- founder: company
- name: campaign a
- """],
- [get_campaign_b(), u"""!campaign
- founder: company
- name: campaign without end
- website_url: http://campaign.com
- """],
- [get_service_a(), u"""!service
- duration: !duration
- years: 2
- ip_addresses:
- - ::1
- location: vienna
- name: service
- price_brutto: !sum '1.0 EUR'
- state: success
- """],
- [get_service_b(), u"""!service
- name: service
- period: !period
- end: null
- start: 2017-04-02 10:23:00
- price_brutto: !sum '1.0 EUR'
- """],
- [get_hosting_service(), u"""!hosting-service
- duration: !duration
- years: 2
- ip_addresses:
- - 127.0.0.1
- - ::1
- location: vienna
- name: virtual server
- operating_system: debian 8
- price_brutto: !sum '1.0 EUR'
- state: running
- """],
- [get_cloud_mining(), u"""!cloud-mining
- hashrate: !figure '8 TH/s'
- name: sha256 BTC
- price_brutto: !sum '1.0 EUR'
- """],
- [get_pledge(), u"""!pledge
- campaign: !campaign
- end: 2016-07-23 09:23:17+01:05
- founder: company
- name: campaign a
- price_brutto: !sum '10.0 EUR'
- reward: great
- """],
- [get_contribution(), u"""!contribution
- campaign: !campaign
- end: 2016-07-23 09:23:17+01:05
- founder: company
- name: campaign a
- price_brutto: !sum '10.0 EUR'
- reward: product
- """],
- [get_order_a(), u"""!order
- customer_id: customer
- discounts:
- - !discount
- amount: !sum '1.23 EUR'
- name: discount a
- - !discount
- amount: !sum '20.45 EUR'
- name: discount β
- items:
- - !item
- name: item a
- price_brutto: !sum '1.23 EUR'
- - !item
- name: item β
- price_brutto: !sum '20.45 EUR'
- order_date: 2016-05-08 00:18:17
- order_id: id
- platform: platformπ
- platform_view_url: http://i.dont.know
- """],
- [get_order_a(discounts = False), u"""!order
- customer_id: customer
- items:
- - !item
- name: item a
- price_brutto: !sum '1.23 EUR'
- - !item
- name: item β
- price_brutto: !sum '20.45 EUR'
- order_date: 2016-05-08 00:18:17
- order_id: id
- platform: platformπ
- platform_view_url: http://i.dont.know
- """],
- [get_article(), u"""!article
- access_option: download
- authors:
- - a
- - b
- depth: !distance '12.3 dm'
- features: supergeil
- height: !distance '123.0 cm'
- maximum_load: !figure '40.0 kg'
- name: article name
- price_brutto: !sum '1.23 EUR'
- product_id: 0815
- quantity: 1
- release_date: 2017-10-24
- reseller: seller
- shipper: shipper
- state: goood
- width: !distance '1.23 m'
- """],
- [get_transportation(period=False), u"""!transportation
- arrival_time: 2016-07-24 23:47:35+02:00
- departure_point: home
- destination_point: city
- distance: !distance '3.21 km'
- estimated_arrival_time: !period
- end: 2016-07-24 23:48:05+00:00
- start: 2016-07-24 23:47:02+02:00
- name: ticket
- passenger: !person
- first_name: Fabian Peter
- last_name: Hammerle
- price_brutto: !sum '1.23 EUR'
- ticket_url: https://www.example.com
- valid_from: 2016-07-14 13:50:04+01:05
- valid_until: 2016-07-14 18:50:04+00:00
- """],
- [get_transportation(period=True), u"""!transportation
- arrival_time: !period
- end: 2016-07-26 23:47:35+02:00
- start: 2016-07-24 23:47:35+02:00
- departure_point: home
- destination_point: city
- distance: !distance '3.21 km'
- estimated_arrival_time: !period
- end: 2016-07-24 23:48:05+00:00
- start: 2016-07-24 23:47:02+02:00
- name: ticket
- passenger: !person
- first_name: Fabian Peter
- last_name: Hammerle
- price_brutto: !sum '1.23 EUR'
- ticket_url: https://www.example.com
- valid_from: 2016-07-14 13:50:04+01:05
- valid_until: 2016-07-14 18:50:04+00:00
- """],
- [get_shipping(), u"""!shipping
- destination_point: home
- price_brutto: !sum '1.23 EUR'
- tracking_number: LX123456789CN
- """],
- [get_taxi_ride(), u"""!taxi-ride
- arrival_time: 2016-05-02 18:10:00+01:05
- departure_point: home
- departure_time: 2016-05-02 18:25:00+01:05
- destination_point: city
- distance: !distance '3.21 km'
- driver: driver
- name: taxi ride
- price_brutto: !sum '1.23 EUR'
- """],
- [get_invoice(), u"""!invoice
- creditor: platformπ
- debitor_id: customer
- discounts:
- - !discount
- amount: !sum '1.23 EUR'
- name: discount a
- invoice_date: 2016-05-08 00:18:17
- invoice_id: id
- invoice_url: http://example.com/invoice.pdf
- items:
- - !item
- name: item a
- price_brutto: !sum '1.23 EUR'
- - !item
- name: item β
- price_brutto: !sum '20.45 EUR'
- """],
- ])
- def test_to_yaml(source_object, expected_yaml):
- assert expected_yaml == to_yaml(source_object)
- @pytest.mark.parametrize('expected_object,source_yaml', [
- [datetime.datetime(2016, 7, 14, 13, 50, 4, 0), '2016-07-14 13:50:04'],
- [datetime.datetime(2016, 7, 14, 13, 50, 4, 0, tzinfo = pytz.timezone('Europe/Vienna')), '2016-07-14 13:50:04+01:05'],
- [datetime.datetime(2016, 7, 14, 13, 50, 4, 0, tzinfo = pytz.utc), '2016-07-14 13:50:04+00:00'],
- [finoex.Distance(1.34, u'km'), u"!distance '1.34 km'\n"],
- [finoex.Distance(1.34, u'μm'), u"!distance '1.34 μm'"],
- [get_discount_a(), u"!discount\nname: discount a\namount: !sum '1.23 EUR'\n"],
- [get_discount_b(), u"!discount\nname: discount β\namount: !sum '20.45 EUR'\n"],
- [get_discount_c(), u"""!discount
- amount: !sum 20.45 EUR
- name: discount c
- code: DISCΓ
- """],
- [get_figure_a(), '!figure\nunit: km\nvalue: 12.3\n'],
- [get_figure_a(), u'!figure\nunit: km\nvalue: 12.3\n'],
- [get_figure_b(), '!figure\nunit: 米\nvalue: 12300\n'],
- [get_figure_b(), u'!figure\nunit: 米\nvalue: 12300\n'],
- [get_item_a(), u"!item\nname: item a\nprice_brutto: !sum '1.23 EUR'\n"],
- [get_item_a(), u"!item\nname: item a\nprice_brutto: !sum 1.23 EUR"],
- [get_item_a(sub_items=True), u"""!item
- name: item a
- price_brutto: !sum '1.23 EUR'
- sub_items:
- - !item
- name: item β
- price_brutto: !sum '20.45 EUR'
- """],
- [get_item_a(), u"!item\nname: item a\nprice_brutto: !sum 1.23 €\n"],
- [get_item_b(), u"!item\nname: item β\nprice_brutto: !sum '20.45 EUR'\n"],
- [get_person_a(), '!person\nfirst_name: Fabian Peter\nlast_name: Hammerle\n'],
- [get_person_a(), u'!person\nfirst_name: Fabian Peter\nlast_name: Hammerle\n'],
- [get_person_b(), u'!person\nfirst_name: 名字\nlast_name: 贵姓\n'],
- [get_campaign_a(), u"""!campaign
- name: campaign a
- founder: company
- end: 2016-07-23 09:23:17+01:05
- """],
- [get_campaign_b(), u"""!campaign
- founder: company
- name: campaign without end
- website_url: http://campaign.com
- """],
- [get_service_a(), u"""!service
- duration: !duration
- years: 2
- ip_addresses:
- - ::1
- location: vienna
- name: service
- price_brutto: !sum '1.0 EUR'
- state: success
- """],
- [get_service_b(), u"""!service
- name: service
- period: !period
- start: 2017-04-02 10:23:00
- price_brutto: !sum '1.0 EUR'
- """],
- [get_hosting_service(), u"""!hosting-service
- duration: !duration
- years: 2
- ip_addresses:
- - 127.0.0.1
- - ::1
- location: vienna
- name: virtual server
- operating_system: debian 8
- price_brutto: !sum '1.0 EUR'
- state: running
- """],
- [get_cloud_mining(), u"""!cloud-mining
- hashrate: !figure 8 TH/s
- name: sha256 BTC
- price_brutto: !sum 1.0 EUR
- """],
- [get_pledge(), u"""!pledge
- campaign: !campaign
- name: campaign a
- founder: company
- end: 2016-07-23 09:23:17+01:05
- price_brutto: !sum '10.0 EUR'
- reward: great
- """],
- [get_contribution(), u"""!contribution
- campaign: !campaign
- end: 2016-07-23 09:23:17+01:05
- founder: company
- name: campaign a
- price_brutto: !sum '10.0 EUR'
- reward: product
- """],
- [[get_person_a(), get_person_b()], u"""
- - !person
- first_name: Fabian Peter
- last_name: Hammerle
- - !person
- first_name: 名字
- last_name: 贵姓"""],
- [get_transportation(period=False), u"""!transportation
- arrival_time: 2016-07-24 23:47:35+02:00
- departure_point: home
- destination_point: city
- distance: !distance '3.21 km'
- name: ticket
- price_brutto: !sum '1.23 EUR'
- route_map: null
- passenger: !person
- first_name: Fabian Peter
- last_name: Hammerle
- ticket_url: https://www.example.com
- valid_from: 2016-07-14 13:50:04+01:05
- valid_until: 2016-07-14 18:50:04+00:00
- estimated_arrival_time: !period
- end: 2016-07-24T23:48:05+00:00
- start: 2016-07-24T23:47:02+02:00
- """],
- [get_transportation(period=True), u"""!transportation
- arrival_time: !period
- end: 2016-07-26 23:47:35+02:00
- start: 2016-07-24 23:47:35+02:00
- departure_point: home
- destination_point: city
- distance: !distance '3.21 km'
- estimated_arrival_time: !period
- end: 2016-07-24 23:48:05+00:00
- start: 2016-07-24 23:47:02+02:00
- name: ticket
- passenger: !person
- first_name: Fabian Peter
- last_name: Hammerle
- price_brutto: !sum '1.23 EUR'
- ticket_url: https://www.example.com
- valid_from: 2016-07-14 13:50:04+01:05
- valid_until: 2016-07-14 18:50:04+00:00
- """],
- [get_shipping(), u"""!shipping
- destination_point: home
- price_brutto: !sum 1.23 EUR
- tracking_number: LX123456789CN
- """],
- [get_order_a(), u"""!order
- customer_id: customer
- discounts:
- - !discount
- amount: !sum '1.23 EUR'
- name: discount a
- - !discount
- amount: !sum '20.45 EUR'
- name: discount β
- items:
- - !item
- name: item a
- price_brutto: !sum '1.23 EUR'
- - !item
- name: item β
- price_brutto: !sum '20.45 EUR'
- order_date: 2016-05-08 00:18:17
- order_id: id
- platform: platformπ
- platform_view_url: http://i.dont.know
- """],
- [get_article(), u"""!article
- access_option: download
- authors:
- - a
- - b
- delivery_date: null
- features: supergeil
- name: article name
- price_brutto: !sum '1.23 EUR'
- product_id: 0815
- quantity: 1
- release_date: 2017-10-24
- reseller: seller
- shipper: shipper
- state: goood
- depth: !distance 12.3 dm
- height: !distance 123.0 cm
- maximum_load: !figure 40.0 kg
- width: !distance 1.23 m
- """],
- [get_taxi_ride(), u"""!taxi-ride
- arrival_time: 2016-05-02 18:10:00+01:05
- departure_point: home
- departure_time: 2016-05-02 18:25:00+01:05
- destination_point: city
- distance: !distance '3.21 km'
- driver: driver
- name: taxi ride
- price_brutto: !sum '1.23 EUR'
- route_map: null
- """],
- [get_invoice(), u"""!invoice
- creditor: platformπ
- debitor_id: customer
- invoice_date: 2016-05-08T00:18:17
- invoice_id: id
- invoice_url: http://example.com/invoice.pdf
- items:
- - !item
- name: item a
- price_brutto: !sum '1.23 EUR'
- - !item
- name: item β
- price_brutto: !sum '20.45 EUR'
- discounts:
- - !discount
- name: discount a
- amount: !sum 1.23 EUR
- """],
- ])
- def test_from_yaml(expected_object, source_yaml):
- class Loader(yaml.Loader):
- pass
- ioex.datetimeex.Duration.register_yaml_constructor(Loader)
- ioex.datetimeex.Period.register_yaml_constructor(Loader)
- ioex.calcex.Figure.register_yaml_constructor(Loader)
- finoex.Sum.register_yaml_constructor(Loader)
- finoex.Distance.register_yaml_constructor(Loader)
- loaded_object = yaml.load(source_yaml, Loader=Loader)
- assert loaded_object == expected_object
|