ptv_timetable 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +115 -0
- data/Rakefile +8 -0
- data/lib/ptv_timetable.rb +12 -0
- data/lib/ptv_timetable/api.rb +61 -0
- data/lib/ptv_timetable/version.rb +3 -0
- data/ptv_timetable.gemspec +27 -0
- data/spec/api_spec.rb +61 -0
- data/spec/spec_helper.rb +2 -0
- metadata +128 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0812a3b2e0e3b1bde01c8965648fdfb0b3a1cecb
|
4
|
+
data.tar.gz: 98633cb2c33caad724bd482dcc3ec92ac26eb940
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0e43c49aa5d7ca56912e30697aa64e813139cdb3d07827f1ba849315877d5b0c93898141d2b949282ce7554721d420664d58571b8ddfdfc03bb756fdc9a56508
|
7
|
+
data.tar.gz: 7c79358dd7d869156091b5f88c0c53345be68840e44d367186a572ad0ad113d4f94eea189d14e65819cab3a856707190749945be9ef28d59cb23405455ff573d
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Neil Ang
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
# PTV Timetable Gem [![Build Status](https://secure.travis-ci.org/neilang/ptv_timetable.png?branch=master)](https://travis-ci.org/neilang/ptv_timetable)
|
2
|
+
|
3
|
+
A ruby gem for interacting with the [PTV timetable API](https://www.data.vic.gov.au/raw_data/ptv-timetable-api/6056) version 2.0.
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
To use this gem you will need to request a `devid` and `secret key`. Instructions on how to do this are available in the [API specificationn](https://www.data.vic.gov.au/raw_data/ptv-timetable-api/6056).
|
8
|
+
|
9
|
+
|
10
|
+
For all API calls you will need a valid _devid_ and _secret_key_.
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
api = PtvTimetable::API.new('devid', 'secret_key')
|
14
|
+
|
15
|
+
```
|
16
|
+
|
17
|
+
### Health Check
|
18
|
+
|
19
|
+
The Health Check will test a number of the key services that deliver the PTV Timetable API and let you know if there are any problems with connectivity, availability or reachability.
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
api.health_check
|
23
|
+
```
|
24
|
+
|
25
|
+
N.B. Calling the Health Check API at the start of each sequence of APIs flushes out any system problems.
|
26
|
+
|
27
|
+
### Stops Nearby
|
28
|
+
|
29
|
+
Stops Nearby returns up to 30 stops nearest to a specified coordinate.
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
api.near_me(-37.82392124423254, 144.9462017431463)
|
33
|
+
```
|
34
|
+
|
35
|
+
### Transport POIs by Map
|
36
|
+
|
37
|
+
Transport POIs by Map returns a set of locations consisting of stops and/or myki ticket outlets (collectively known as points of interest) within a region demarcated on a map through a set of latitude and longitude coordinates.
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
api.points_of_interest(-37.82205143151239, 144.9779160007277, -37.81393456848758, 144.9859159992726)
|
41
|
+
```
|
42
|
+
|
43
|
+
### Search
|
44
|
+
|
45
|
+
The Search API returns all stops and lines that match the input search text.
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
api.search('Alamein')
|
49
|
+
```
|
50
|
+
|
51
|
+
### Broad Next Departures
|
52
|
+
|
53
|
+
Broad Next Departures returns the next departure times at a prescribed stop irrespective of the line and direction of the service.
|
54
|
+
|
55
|
+
For example, if the stop is Camberwell Station, Broad Next Departures will return the times for all three lines (Belgrave, Lilydale and Alamein) running in both directions (towards the city and away from the city).
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
api.broad_next_departures(PtvTimetable::BUS, 28905)
|
59
|
+
```
|
60
|
+
|
61
|
+
# Specific Next Departures
|
62
|
+
|
63
|
+
Specific Next Departures returns the times for the next departures at a prescribed stop for a specific mode, line and direction.
|
64
|
+
|
65
|
+
For example, if the stop is Camberwell Station, Specific Next Departures returns only the times
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
api.specific_next_departures(PtvTimetable::BUS, 5111, 2896, 28905, 515)
|
69
|
+
```
|
70
|
+
|
71
|
+
### Stopping Pattern
|
72
|
+
|
73
|
+
The Stopping Pattern API returns the stopping pattern for a specific run (i.e. transport service) from a prescribed stop at a prescribed time. The stopping pattern is comprised of timetable values ordered by stopping order.
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
api.stopping_pattern(PtvTimetable::BUS, 1464, 1108, '2013-11-13T05:24:25Z')
|
77
|
+
```
|
78
|
+
|
79
|
+
### Stops on a Line
|
80
|
+
|
81
|
+
The Stops on a Line API returns a list of all the stops for a requested line, ordered by location name.
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
api.line_stops(PtvTimetable::BUS, 1818)
|
85
|
+
|
86
|
+
```
|
87
|
+
|
88
|
+
## Installation
|
89
|
+
|
90
|
+
Add this line to your application's Gemfile:
|
91
|
+
|
92
|
+
gem 'ptv_timetable'
|
93
|
+
|
94
|
+
And then execute:
|
95
|
+
|
96
|
+
$ bundle
|
97
|
+
|
98
|
+
Or install it yourself as:
|
99
|
+
|
100
|
+
$ gem install ptv_timetable
|
101
|
+
|
102
|
+
|
103
|
+
## Contributing
|
104
|
+
|
105
|
+
1. Fork it ( http://github.com/neilang/ptv_timetable/fork )
|
106
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
107
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
108
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
109
|
+
5. Create new Pull Request
|
110
|
+
|
111
|
+
## Disclaimer & Attribution
|
112
|
+
|
113
|
+
This ruby gem and it's developers are in no way affiliated with Public Transport Victoria (PTV). Any trademarks referred to are the property of their respective trademark holders. We declare no affiliation, sponsorship, nor any partnerships with any registered trademarks.
|
114
|
+
|
115
|
+
The API specification titled "Timetable API" was released under the Creative Commons license. I attribute this publication - _Source: Licensed from Public Transport Victoria under a Creative Commons Attribution 3.0 Australia Licence._
|
data/Rakefile
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
module PtvTimetable
|
5
|
+
|
6
|
+
class API
|
7
|
+
include HTTParty
|
8
|
+
|
9
|
+
base_uri 'http://timetableapi.ptv.vic.gov.au'
|
10
|
+
|
11
|
+
def initialize(devid, secret_key)
|
12
|
+
@devid = devid
|
13
|
+
@secret_key = secret_key
|
14
|
+
end
|
15
|
+
|
16
|
+
def health_check(timestamp=Time.now.utc.iso8601)
|
17
|
+
signed_request("/v2/healthcheck?timestamp=#{timestamp}")
|
18
|
+
end
|
19
|
+
|
20
|
+
def near_me(latitude, longitude)
|
21
|
+
signed_request("/v2/nearme/latitude/#{latitude}/longitude/#{longitude}")
|
22
|
+
end
|
23
|
+
|
24
|
+
def points_of_interest(latitude1, longitude1, latitude2, longitude2)
|
25
|
+
poi = '0,1,2,3,4,100'
|
26
|
+
grid_depth = 3
|
27
|
+
limit = 6
|
28
|
+
signed_request("/v2/poi/#{poi}/lat1/#{latitude1}/long1/#{longitude1}/lat2/#{latitude2}/long2/#{latitude2}/griddepth/#{grid_depth}/limit/#{limit}")
|
29
|
+
end
|
30
|
+
|
31
|
+
def search(text)
|
32
|
+
signed_request("/v2/search/#{text}")
|
33
|
+
end
|
34
|
+
|
35
|
+
def broad_next_departures(mode, stop, limit=5)
|
36
|
+
signed_request("/v2/mode/#{mode}/stop/#{stop}/departures/by-destination/limit/#{limit}")
|
37
|
+
end
|
38
|
+
|
39
|
+
def specific_next_departures(mode, line, stop, direction, limit=5, utc=Time.now.utc.iso8601)
|
40
|
+
signed_request("/v2/mode/#{mode}/line/#{line}/stop/#{stop}/directionid/#{direction}/departures/all/limit/#{limit}?for_utc=#{utc}")
|
41
|
+
end
|
42
|
+
|
43
|
+
def stopping_pattern(mode, run, stop, utc=Time.now.utc.iso8601)
|
44
|
+
signed_request("/v2/mode/#{mode}/run/#{run}/stop/#{stop}/stopping-pattern?for_utc=#{utc}")
|
45
|
+
end
|
46
|
+
|
47
|
+
def line_stops(mode, line)
|
48
|
+
signed_request("/v2/mode/#{mode}/line/#{line}/stops-for-line")
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def signed_request(request_path)
|
54
|
+
request_path += (request_path.include?('?') ? '&' : '?') + "devid=#{@devid}"
|
55
|
+
signature = Digest::HMAC.hexdigest(request_path, @secret_key, Digest::SHA1).upcase
|
56
|
+
self.class.get("#{request_path}&signature=#{signature}").parsed_response
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'ptv_timetable/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "ptv_timetable"
|
8
|
+
spec.version = PtvTimetable::VERSION
|
9
|
+
spec.authors = ["Neil Ang"]
|
10
|
+
spec.email = ["neilang@gmail.com"]
|
11
|
+
spec.summary = %q{A ruby gem for interacting with the PTV timetable API.}
|
12
|
+
spec.description = %q{A ruby gem for interacting with the PTV timetable API.}
|
13
|
+
spec.homepage = "https://github.com/neilang/ptv_timetable"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec", "~> 2.14.1"
|
24
|
+
spec.add_development_dependency "webmock", "~> 1.17.4"
|
25
|
+
|
26
|
+
spec.add_dependency "httparty", "~> 0.13.0"
|
27
|
+
end
|
data/spec/api_spec.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe PtvTimetable::API do
|
4
|
+
|
5
|
+
let(:subject){ PtvTimetable::API.new('devid', 'secret') }
|
6
|
+
|
7
|
+
it "should treat the devid and secret as required" do
|
8
|
+
expect{
|
9
|
+
PtvTimetable::API.new
|
10
|
+
}.to raise_error(ArgumentError)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'can request a health check' do
|
14
|
+
stub = stub_request(:get, "http://timetableapi.ptv.vic.gov.au/v2/healthcheck?devid=devid&signature=3258AF3DE4CB58FD54F13445D149560B6E9B923C×tamp=2013-11-13T05:24:25Z")
|
15
|
+
subject.health_check('2013-11-13T05:24:25Z')
|
16
|
+
stub.should have_been_requested
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'can search near me' do
|
20
|
+
stub = stub_request(:get, "http://timetableapi.ptv.vic.gov.au/v2/nearme/latitude/-37.82392124423254/longitude/144.9462017431463?devid=devid&signature=DA23BFC88EB80BF3EB0AC59AF5846159C0F6EFE2")
|
21
|
+
subject.near_me(-37.82392124423254, 144.9462017431463)
|
22
|
+
stub.should have_been_requested
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'can find points of interest' do
|
26
|
+
stub = stub_request(:get, "http://timetableapi.ptv.vic.gov.au/v2/poi/0,1,2,3,4,100/lat1/-37.82205143151239/long1/144.9779160007277/lat2/-37.81393456848758/long2/-37.81393456848758/griddepth/3/limit/6?devid=devid&signature=F94A5E7774028E67B6684B17E1C49886C5BEFBC9")
|
27
|
+
subject.points_of_interest(-37.82205143151239, 144.9779160007277, -37.81393456848758, 144.9859159992726)
|
28
|
+
stub.should have_been_requested
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'can perform a general search' do
|
32
|
+
stub = stub_request(:get, "http://timetableapi.ptv.vic.gov.au/v2/search/Alamein?devid=devid&signature=17E15574BF165335DD054E02FC5F8C5C33189262")
|
33
|
+
subject.search('Alamein')
|
34
|
+
stub.should have_been_requested
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'can lookup broad next departures' do
|
38
|
+
stub = stub_request(:get, "http://timetableapi.ptv.vic.gov.au/v2/mode/2/stop/28905/departures/by-destination/limit/5?devid=devid&signature=8AB75EF37D089BDD055327FB8559350215CFBFB4")
|
39
|
+
subject.broad_next_departures(PtvTimetable::BUS, 28905)
|
40
|
+
stub.should have_been_requested
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'can lookup specific next departures' do
|
44
|
+
stub = stub_request(:get, "http://timetableapi.ptv.vic.gov.au/v2/mode/2/line/5111/stop/2896/directionid/28905/departures/all/limit/515?devid=devid&for_utc=2013-11-13T05:24:25Z&signature=F373732C2A31DE7B3053FE26D3C5C8449F1C980A")
|
45
|
+
subject.specific_next_departures(PtvTimetable::BUS, 5111, 2896, 28905, 515, '2013-11-13T05:24:25Z')
|
46
|
+
stub.should have_been_requested
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'can lookup a stopping pattern' do
|
50
|
+
stub = stub_request(:get, "http://timetableapi.ptv.vic.gov.au/v2/mode/2/run/1464/stop/1108/stopping-pattern?devid=devid&for_utc=2013-11-13T05:24:25Z&signature=345F61EE77EFD7D25E56672D84CFC1D37C794EF5")
|
51
|
+
subject.stopping_pattern(PtvTimetable::BUS, 1464, 1108, '2013-11-13T05:24:25Z')
|
52
|
+
stub.should have_been_requested
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'can lookup stops on a line' do
|
56
|
+
stub = stub_request(:get, "http://timetableapi.ptv.vic.gov.au/v2/mode/2/line/1818/stops-for-line?devid=devid&signature=42FE7A31C9474B199DC38BE4E23ADA606878DF6A")
|
57
|
+
subject.line_stops(PtvTimetable::BUS, 1818)
|
58
|
+
stub.should have_been_requested
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ptv_timetable
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Neil Ang
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-03-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.5'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 2.14.1
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 2.14.1
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: webmock
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.17.4
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 1.17.4
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: httparty
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.13.0
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.13.0
|
83
|
+
description: A ruby gem for interacting with the PTV timetable API.
|
84
|
+
email:
|
85
|
+
- neilang@gmail.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- ".travis.yml"
|
92
|
+
- Gemfile
|
93
|
+
- LICENSE.txt
|
94
|
+
- README.md
|
95
|
+
- Rakefile
|
96
|
+
- lib/ptv_timetable.rb
|
97
|
+
- lib/ptv_timetable/api.rb
|
98
|
+
- lib/ptv_timetable/version.rb
|
99
|
+
- ptv_timetable.gemspec
|
100
|
+
- spec/api_spec.rb
|
101
|
+
- spec/spec_helper.rb
|
102
|
+
homepage: https://github.com/neilang/ptv_timetable
|
103
|
+
licenses:
|
104
|
+
- MIT
|
105
|
+
metadata: {}
|
106
|
+
post_install_message:
|
107
|
+
rdoc_options: []
|
108
|
+
require_paths:
|
109
|
+
- lib
|
110
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0'
|
120
|
+
requirements: []
|
121
|
+
rubyforge_project:
|
122
|
+
rubygems_version: 2.2.0
|
123
|
+
signing_key:
|
124
|
+
specification_version: 4
|
125
|
+
summary: A ruby gem for interacting with the PTV timetable API.
|
126
|
+
test_files:
|
127
|
+
- spec/api_spec.rb
|
128
|
+
- spec/spec_helper.rb
|