fog 0.0.56 → 0.0.57

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. data/Rakefile +1 -1
  2. data/VERSION.yml +1 -1
  3. data/fog.gemspec +4 -4
  4. data/lib/fog/aws.rb +4 -3
  5. data/lib/fog/aws/ec2.rb +136 -150
  6. data/lib/fog/aws/models/ec2/address.rb +3 -1
  7. data/lib/fog/aws/models/ec2/addresses.rb +20 -6
  8. data/lib/fog/aws/models/ec2/flavor.rb +3 -1
  9. data/lib/fog/aws/models/ec2/flavors.rb +14 -3
  10. data/lib/fog/aws/models/ec2/image.rb +3 -1
  11. data/lib/fog/aws/models/ec2/images.rb +14 -3
  12. data/lib/fog/aws/models/ec2/key_pair.rb +3 -1
  13. data/lib/fog/aws/models/ec2/key_pairs.rb +14 -3
  14. data/lib/fog/aws/models/ec2/security_group.rb +3 -1
  15. data/lib/fog/aws/models/ec2/security_groups.rb +14 -3
  16. data/lib/fog/aws/models/ec2/server.rb +3 -1
  17. data/lib/fog/aws/models/ec2/servers.rb +14 -3
  18. data/lib/fog/aws/models/ec2/snapshot.rb +3 -1
  19. data/lib/fog/aws/models/ec2/snapshots.rb +18 -5
  20. data/lib/fog/aws/models/ec2/volume.rb +3 -1
  21. data/lib/fog/aws/models/ec2/volumes.rb +18 -5
  22. data/lib/fog/aws/models/s3/directories.rb +14 -3
  23. data/lib/fog/aws/models/s3/directory.rb +4 -1
  24. data/lib/fog/aws/models/s3/file.rb +3 -1
  25. data/lib/fog/aws/models/s3/files.rb +4 -1
  26. data/lib/fog/aws/parsers/simpledb/domain_metadata.rb +2 -0
  27. data/lib/fog/aws/parsers/simpledb/get_attributes.rb +2 -0
  28. data/lib/fog/aws/parsers/simpledb/list_domains.rb +2 -0
  29. data/lib/fog/aws/parsers/simpledb/select.rb +2 -0
  30. data/lib/fog/aws/requests/ec2/allocate_address.rb +11 -16
  31. data/lib/fog/aws/requests/ec2/associate_address.rb +14 -19
  32. data/lib/fog/aws/requests/ec2/attach_volume.rb +16 -21
  33. data/lib/fog/aws/requests/ec2/authorize_security_group_ingress.rb +29 -27
  34. data/lib/fog/aws/requests/ec2/create_key_pair.rb +13 -18
  35. data/lib/fog/aws/requests/ec2/create_security_group.rb +14 -19
  36. data/lib/fog/aws/requests/ec2/create_snapshot.rb +13 -18
  37. data/lib/fog/aws/requests/ec2/create_volume.rb +14 -19
  38. data/lib/fog/aws/requests/ec2/delete_key_pair.rb +12 -17
  39. data/lib/fog/aws/requests/ec2/delete_security_group.rb +13 -18
  40. data/lib/fog/aws/requests/ec2/delete_snapshot.rb +12 -17
  41. data/lib/fog/aws/requests/ec2/delete_volume.rb +13 -18
  42. data/lib/fog/aws/requests/ec2/describe_addresses.rb +11 -16
  43. data/lib/fog/aws/requests/ec2/describe_availability_zones.rb +9 -14
  44. data/lib/fog/aws/requests/ec2/describe_images.rb +9 -14
  45. data/lib/fog/aws/requests/ec2/describe_instances.rb +17 -22
  46. data/lib/fog/aws/requests/ec2/describe_key_pairs.rb +11 -16
  47. data/lib/fog/aws/requests/ec2/describe_regions.rb +9 -14
  48. data/lib/fog/aws/requests/ec2/describe_reserved_instances.rb +9 -14
  49. data/lib/fog/aws/requests/ec2/describe_security_groups.rb +11 -16
  50. data/lib/fog/aws/requests/ec2/describe_snapshots.rb +12 -17
  51. data/lib/fog/aws/requests/ec2/describe_volumes.rb +14 -19
  52. data/lib/fog/aws/requests/ec2/detach_volume.rb +11 -16
  53. data/lib/fog/aws/requests/ec2/disassociate_address.rb +12 -17
  54. data/lib/fog/aws/requests/ec2/get_console_output.rb +12 -17
  55. data/lib/fog/aws/requests/ec2/reboot_instances.rb +11 -16
  56. data/lib/fog/aws/requests/ec2/release_address.rb +12 -17
  57. data/lib/fog/aws/requests/ec2/revoke_security_group_ingress.rb +10 -15
  58. data/lib/fog/aws/requests/ec2/run_instances.rb +36 -38
  59. data/lib/fog/aws/requests/ec2/terminate_instances.rb +16 -20
  60. data/lib/fog/aws/requests/s3/copy_object.rb +9 -15
  61. data/lib/fog/aws/requests/s3/delete_bucket.rb +9 -16
  62. data/lib/fog/aws/requests/s3/delete_object.rb +6 -14
  63. data/lib/fog/aws/requests/s3/get_bucket.rb +9 -14
  64. data/lib/fog/aws/requests/s3/get_bucket_location.rb +8 -14
  65. data/lib/fog/aws/requests/s3/get_object.rb +7 -15
  66. data/lib/fog/aws/requests/s3/get_request_payment.rb +7 -13
  67. data/lib/fog/aws/requests/s3/get_service.rb +7 -13
  68. data/lib/fog/aws/requests/s3/head_object.rb +6 -14
  69. data/lib/fog/aws/requests/s3/put_bucket.rb +13 -21
  70. data/lib/fog/aws/requests/s3/put_object.rb +8 -16
  71. data/lib/fog/aws/requests/s3/put_request_payment.rb +7 -16
  72. data/lib/fog/aws/requests/simpledb/batch_put_attributes.rb +14 -21
  73. data/lib/fog/aws/requests/simpledb/create_domain.rb +11 -18
  74. data/lib/fog/aws/requests/simpledb/delete_attributes.rb +15 -22
  75. data/lib/fog/aws/requests/simpledb/delete_domain.rb +11 -18
  76. data/lib/fog/aws/requests/simpledb/domain_metadata.rb +14 -19
  77. data/lib/fog/aws/requests/simpledb/get_attributes.rb +19 -23
  78. data/lib/fog/aws/requests/simpledb/list_domains.rb +11 -16
  79. data/lib/fog/aws/requests/simpledb/put_attributes.rb +15 -15
  80. data/lib/fog/aws/requests/simpledb/select.rb +12 -17
  81. data/lib/fog/aws/s3.rb +117 -121
  82. data/lib/fog/aws/simpledb.rb +127 -127
  83. data/lib/fog/rackspace/models/servers/images.rb +1 -1
  84. data/spec/aws/requests/ec2/authorize_security_group_ingress_spec.rb +11 -1
  85. metadata +4 -4
@@ -1,8 +1,7 @@
1
- unless Fog.mocking?
2
-
3
- module Fog
4
- module AWS
5
- class S3
1
+ module Fog
2
+ module AWS
3
+ module S3
4
+ class Real
6
5
 
7
6
  # Create an S3 bucket
8
7
  #
@@ -17,11 +16,11 @@ unless Fog.mocking?
17
16
  def put_bucket(bucket_name, options = {})
18
17
  if options['LocationConstraint']
19
18
  data =
20
- <<-DATA
21
- <CreateBucketConfiguration>
22
- <LocationConstraint>#{options['LocationConstraint']}</LocationConstraint>
23
- </CreateBucketConfiguration>
24
- DATA
19
+ <<-DATA
20
+ <CreateBucketConfiguration>
21
+ <LocationConstraint>#{options['LocationConstraint']}</LocationConstraint>
22
+ </CreateBucketConfiguration>
23
+ DATA
25
24
  else
26
25
  data = nil
27
26
  end
@@ -36,14 +35,8 @@ unless Fog.mocking?
36
35
  end
37
36
 
38
37
  end
39
- end
40
- end
41
38
 
42
- else
43
-
44
- module Fog
45
- module AWS
46
- class S3
39
+ class Mock
47
40
 
48
41
  def put_bucket(bucket_name, options = {})
49
42
  response = Excon::Response.new
@@ -60,8 +53,8 @@ else
60
53
  else
61
54
  bucket['LocationConstraint'] = ''
62
55
  end
63
- unless Fog::AWS::S3.data[:buckets][bucket_name]
64
- Fog::AWS::S3.data[:buckets][bucket_name] = bucket
56
+ unless @data[:buckets][bucket_name]
57
+ @data[:buckets][bucket_name] = bucket
65
58
  end
66
59
  response
67
60
  end
@@ -69,5 +62,4 @@ else
69
62
  end
70
63
  end
71
64
  end
72
-
73
- end
65
+ end
@@ -1,8 +1,7 @@
1
- unless Fog.mocking?
2
-
3
- module Fog
4
- module AWS
5
- class S3
1
+ module Fog
2
+ module AWS
3
+ module S3
4
+ class Real
6
5
 
7
6
  # Create an object in an S3 bucket
8
7
  #
@@ -25,7 +24,7 @@ unless Fog.mocking?
25
24
  # * headers<~Hash>:
26
25
  # * 'ETag'<~String> - etag of new object
27
26
  def put_object(bucket_name, object_name, data, options = {})
28
- data = parse_data(data)
27
+ data = Fog::AWS::S3.parse_data(data)
29
28
  headers = data[:headers].merge!(options)
30
29
  request({
31
30
  :body => data[:body],
@@ -39,19 +38,13 @@ unless Fog.mocking?
39
38
  end
40
39
 
41
40
  end
42
- end
43
- end
44
41
 
45
- else
46
-
47
- module Fog
48
- module AWS
49
- class S3
42
+ class Mock
50
43
 
51
44
  def put_object(bucket_name, object_name, data, options = {})
52
- data = parse_data(data)
45
+ data = Fog::AWS::S3.parse_data(data)
53
46
  response = Excon::Response.new
54
- if (bucket = Fog::AWS::S3.data[:buckets][bucket_name])
47
+ if (bucket = @data[:buckets][bucket_name])
55
48
  response.status = 200
56
49
  bucket[:objects][object_name] = {
57
50
  :body => data[:body],
@@ -72,5 +65,4 @@ else
72
65
  end
73
66
  end
74
67
  end
75
-
76
68
  end
@@ -1,8 +1,7 @@
1
- unless Fog.mocking?
2
-
3
- module Fog
4
- module AWS
5
- class S3
1
+ module Fog
2
+ module AWS
3
+ module S3
4
+ class Real
6
5
 
7
6
  # Change who pays for requests to an S3 bucket
8
7
  #
@@ -27,18 +26,12 @@ DATA
27
26
  end
28
27
 
29
28
  end
30
- end
31
- end
32
29
 
33
- else
34
-
35
- module Fog
36
- module AWS
37
- class S3
30
+ class Mock
38
31
 
39
32
  def put_request_payment(bucket_name, payer)
40
33
  response = Excon::Response.new
41
- if bucket = Fog::AWS::S3.data[:buckets][bucket_name]
34
+ if bucket = @data[:buckets][bucket_name]
42
35
  response.status = 200
43
36
  bucket['Payer'] = payer
44
37
  else
@@ -51,6 +44,4 @@ else
51
44
  end
52
45
  end
53
46
  end
54
-
55
-
56
- end
47
+ end
@@ -1,8 +1,7 @@
1
- unless Fog.mocking?
2
-
3
- module Fog
4
- module AWS
5
- class SimpleDB
1
+ module Fog
2
+ module AWS
3
+ module SimpleDB
4
+ class Real
6
5
 
7
6
  # Put items attributes into a SimpleDB domain
8
7
  #
@@ -23,33 +22,28 @@ unless Fog.mocking?
23
22
  # * 'RequestId'
24
23
  def batch_put_attributes(domain_name, items, replace_attributes = Hash.new([]))
25
24
  request({
26
- 'Action' => 'BatchPutAttributes',
27
- 'DomainName' => domain_name
28
- }.merge!(encode_batch_attributes(items, replace_attributes)), Fog::Parsers::AWS::SimpleDB::Basic.new(@nil_string))
25
+ 'Action' => 'BatchPutAttributes',
26
+ 'DomainName' => domain_name,
27
+ :parser => Fog::Parsers::AWS::SimpleDB::Basic.new(@nil_string)
28
+ }.merge!(encode_batch_attributes(items, replace_attributes)))
29
29
  end
30
30
 
31
31
  end
32
- end
33
- end
34
32
 
35
- else
36
-
37
- module Fog
38
- module AWS
39
- class SimpleDB
33
+ class Mock
40
34
 
41
35
  def batch_put_attributes(domain_name, items, replace_attributes = Hash.new([]))
42
36
  response = Excon::Response.new
43
- if Fog::AWS::SimpleDB.data[:domains][domain_name]
37
+ if @data[:domains][domain_name]
44
38
  for item_name, attributes in items do
45
39
  for key, value in attributes do
46
- Fog::AWS::SimpleDB.data[:domains][domain_name][item_name] ||= {}
40
+ @data[:domains][domain_name][item_name] ||= {}
47
41
  if replace_attributes[item_name] && replace_attributes[item_name].include?(key)
48
- Fog::AWS::SimpleDB.data[:domains][domain_name][item_name][key.to_s] = []
42
+ @data[:domains][domain_name][item_name][key.to_s] = []
49
43
  else
50
- Fog::AWS::SimpleDB.data[:domains][domain_name][item_name][key.to_s] ||= []
44
+ @data[:domains][domain_name][item_name][key.to_s] ||= []
51
45
  end
52
- Fog::AWS::SimpleDB.data[:domains][domain_name][item_name][key.to_s] << value.to_s
46
+ @data[:domains][domain_name][item_name][key.to_s] << value.to_s
53
47
  end
54
48
  end
55
49
  response.status = 200
@@ -67,5 +61,4 @@ else
67
61
  end
68
62
  end
69
63
  end
70
-
71
64
  end
@@ -1,8 +1,7 @@
1
- unless Fog.mocking?
2
-
3
- module Fog
4
- module AWS
5
- class SimpleDB
1
+ module Fog
2
+ module AWS
3
+ module SimpleDB
4
+ class Real
6
5
 
7
6
  # Create a SimpleDB domain
8
7
  #
@@ -16,25 +15,20 @@ unless Fog.mocking?
16
15
  # * 'BoxUsage'
17
16
  # * 'RequestId'
18
17
  def create_domain(domain_name)
19
- request({
20
- 'Action' => 'CreateDomain',
21
- 'DomainName' => domain_name
22
- }, Fog::Parsers::AWS::SimpleDB::Basic.new(@nil_string))
18
+ request(
19
+ 'Action' => 'CreateDomain',
20
+ 'DomainName' => domain_name,
21
+ :parser => Fog::Parsers::AWS::SimpleDB::Basic.new(@nil_string)
22
+ )
23
23
  end
24
24
 
25
25
  end
26
- end
27
- end
28
26
 
29
- else
30
-
31
- module Fog
32
- module AWS
33
- class SimpleDB
27
+ class Mock
34
28
 
35
29
  def create_domain(domain_name)
36
30
  response = Excon::Response.new
37
- Fog::AWS::SimpleDB.data[:domains][domain_name] = {}
31
+ @data[:domains][domain_name] = {}
38
32
  response.status = 200
39
33
  response.body = {
40
34
  'BoxUsage' => Fog::AWS::Mock.box_usage,
@@ -46,5 +40,4 @@ else
46
40
  end
47
41
  end
48
42
  end
49
-
50
43
  end
@@ -1,8 +1,7 @@
1
- unless Fog.mocking?
2
-
3
- module Fog
4
- module AWS
5
- class SimpleDB
1
+ module Fog
2
+ module AWS
3
+ module SimpleDB
4
+ class Real
6
5
 
7
6
  # List metadata for SimpleDB domain
8
7
  #
@@ -25,33 +24,28 @@ unless Fog.mocking?
25
24
  # * 'RequestId'
26
25
  def delete_attributes(domain_name, item_name, attributes = nil)
27
26
  request({
28
- 'Action' => 'DeleteAttributes',
29
- 'DomainName' => domain_name,
30
- 'ItemName' => item_name
31
- }.merge!(encode_attributes(attributes)), Fog::Parsers::AWS::SimpleDB::Basic.new(@nil_string))
27
+ 'Action' => 'DeleteAttributes',
28
+ 'DomainName' => domain_name,
29
+ 'ItemName' => item_name,
30
+ :parser => Fog::Parsers::AWS::SimpleDB::Basic.new(@nil_string)
31
+ }.merge!(encode_attributes(attributes)))
32
32
  end
33
33
 
34
34
  end
35
- end
36
- end
37
35
 
38
- else
39
-
40
- module Fog
41
- module AWS
42
- class SimpleDB
36
+ class Mock
43
37
 
44
38
  def delete_attributes(domain_name, item_name, attributes = nil)
45
39
  response = Excon::Response.new
46
- if Fog::AWS::SimpleDB.data[:domains][domain_name]
40
+ if @data[:domains][domain_name]
47
41
  if attributes
48
42
  for key, value in attributes
49
- if Fog::AWS::SimpleDB.data[:domains][domain_name][key]
50
- Fog::AWS::SimpleDB.data[:domains][domain_name][key].delete('value')
43
+ if @data[:domains][domain_name][key]
44
+ @data[:domains][domain_name][key].delete('value')
51
45
  end
52
46
  end
53
47
  else
54
- Fog::AWS::SimpleDB.data[:domains].delete(domain_name)
48
+ @data[:domains].delete(domain_name)
55
49
  end
56
50
  response.status = 200
57
51
  response.body = {
@@ -68,5 +62,4 @@ else
68
62
  end
69
63
  end
70
64
  end
71
-
72
- end
65
+ end
@@ -1,8 +1,7 @@
1
- unless Fog.mocking?
2
-
3
- module Fog
4
- module AWS
5
- class SimpleDB
1
+ module Fog
2
+ module AWS
3
+ module SimpleDB
4
+ class Real
6
5
 
7
6
  # Delete a SimpleDB domain
8
7
  #
@@ -16,25 +15,20 @@ unless Fog.mocking?
16
15
  # * 'BoxUsage'
17
16
  # * 'RequestId'
18
17
  def delete_domain(domain_name)
19
- request({
20
- 'Action' => 'DeleteDomain',
21
- 'DomainName' => domain_name
22
- }, Fog::Parsers::AWS::SimpleDB::Basic.new(@nil_string))
18
+ request(
19
+ 'Action' => 'DeleteDomain',
20
+ 'DomainName' => domain_name,
21
+ :parser => Fog::Parsers::AWS::SimpleDB::Basic.new(@nil_string)
22
+ )
23
23
  end
24
24
 
25
25
  end
26
- end
27
- end
28
26
 
29
- else
30
-
31
- module Fog
32
- module AWS
33
- class SimpleDB
27
+ class Mock
34
28
 
35
29
  def delete_domain(domain_name)
36
30
  response = Excon::Response.new
37
- if Fog::AWS::SimpleDB.data[:domains].delete(domain_name)
31
+ if @data[:domains].delete(domain_name)
38
32
  response.status = 200
39
33
  response.body = {
40
34
  'BoxUsage' => Fog::AWS::Mock.box_usage,
@@ -47,5 +41,4 @@ else
47
41
  end
48
42
  end
49
43
  end
50
-
51
44
  end
@@ -1,8 +1,9 @@
1
- unless Fog.mocking?
1
+ module Fog
2
+ module AWS
3
+ module SimpleDB
4
+ class Real
2
5
 
3
- module Fog
4
- module AWS
5
- class SimpleDB
6
+ require 'fog/aws/parsers/simpledb/domain_metadata'
6
7
 
7
8
  # List metadata for SimpleDB domain
8
9
  #
@@ -23,27 +24,22 @@ unless Fog.mocking?
23
24
  # * 'RequestId'
24
25
  # * 'Timestamp' - last update time for metadata.
25
26
  def domain_metadata(domain_name)
26
- request({
27
- 'Action' => 'DomainMetadata',
28
- 'DomainName' => domain_name
29
- }, Fog::Parsers::AWS::SimpleDB::DomainMetadata.new(@nil_string))
27
+ request(
28
+ 'Action' => 'DomainMetadata',
29
+ 'DomainName' => domain_name,
30
+ :parser => Fog::Parsers::AWS::SimpleDB::DomainMetadata.new(@nil_string)
31
+ )
30
32
  end
31
33
 
32
34
  end
33
- end
34
- end
35
35
 
36
- else
37
-
38
- module Fog
39
- module AWS
40
- class SimpleDB
36
+ class Mock
41
37
 
42
38
  def domain_metadata(domain_name)
43
39
  response = Excon::Response.new
44
- if domain = Fog::AWS::SimpleDB.data[:domains][domain_name]
40
+ if domain = @data[:domains][domain_name]
45
41
  response.status = 200
46
-
42
+
47
43
  attribute_names = []
48
44
  attribute_values = []
49
45
  for item in domain.values
@@ -54,7 +50,7 @@ else
54
50
  end
55
51
  end
56
52
  end
57
-
53
+
58
54
  response.body = {
59
55
  'AttributeNameCount' => attribute_names.length,
60
56
  'AttributeNamesSizeBytes' => attribute_names.join('').length,
@@ -76,5 +72,4 @@ else
76
72
  end
77
73
  end
78
74
  end
79
-
80
75
  end
@@ -1,8 +1,9 @@
1
- unless Fog.mocking?
1
+ module Fog
2
+ module AWS
3
+ module SimpleDB
4
+ class Real
2
5
 
3
- module Fog
4
- module AWS
5
- class SimpleDB
6
+ require 'fog/aws/parsers/simpledb/get_attributes'
6
7
 
7
8
  # List metadata for SimpleDB domain
8
9
  #
@@ -13,7 +14,7 @@ unless Fog.mocking?
13
14
  # in xml. Control characters and sequences not allowed in xml are not
14
15
  # valid. Can be up to 1024 bytes long.
15
16
  # * attributes<~Array> - Attributes to return from the item. Defaults to
16
- # nil, which will return all attributes. Attribute names and values may use
17
+ # {}, which will return all attributes. Attribute names and values may use
17
18
  # any UTF-8 characters valid in xml. Control characters and sequences not
18
19
  # allowed in xml are not valid. Each name and value can be up to 1024
19
20
  # bytes long.
@@ -24,36 +25,32 @@ unless Fog.mocking?
24
25
  # * 'Attributes' - list of attribute name/values for the item
25
26
  # * 'BoxUsage'
26
27
  # * 'RequestId'
27
- def get_attributes(domain_name, item_name, attributes = nil)
28
+ def get_attributes(domain_name, item_name, attributes = {})
29
+
28
30
  request({
29
- 'Action' => 'GetAttributes',
30
- 'DomainName' => domain_name,
31
- 'ItemName' => item_name,
32
- }.merge!(encode_attribute_names(attributes)), Fog::Parsers::AWS::SimpleDB::GetAttributes.new(@nil_string))
31
+ 'Action' => 'GetAttributes',
32
+ 'DomainName' => domain_name,
33
+ 'ItemName' => item_name,
34
+ :parser => Fog::Parsers::AWS::SimpleDB::GetAttributes.new(@nil_string)
35
+ }.merge!(encode_attribute_names(attributes)))
33
36
  end
34
37
 
35
38
  end
36
- end
37
- end
38
39
 
39
- else
40
-
41
- module Fog
42
- module AWS
43
- class SimpleDB
40
+ class Mock
44
41
 
45
42
  def get_attributes(domain_name, item_name, attributes = nil)
46
43
  response = Excon::Response.new
47
- if Fog::AWS::SimpleDB.data[:domains][domain_name]
44
+ if @data[:domains][domain_name]
48
45
  object = {}
49
46
  if attributes
50
47
  for attribute in attributes
51
- if Fog::AWS::SimpleDB.data[:domains][domain_name][item_name] && Fog::AWS::SimpleDB.data[:domains][domain_name][item_name]
52
- object[attribute] = Fog::AWS::SimpleDB.data[:domains][domain_name][item_name][attribute]
48
+ if @data[:domains][domain_name][item_name] && @data[:domains][domain_name][item_name]
49
+ object[attribute] = @data[:domains][domain_name][item_name][attribute]
53
50
  end
54
51
  end
55
- elsif Fog::AWS::SimpleDB.data[:domains][domain_name][item_name]
56
- object = Fog::AWS::SimpleDB.data[:domains][domain_name][item_name]
52
+ elsif @data[:domains][domain_name][item_name]
53
+ object = @data[:domains][domain_name][item_name]
57
54
  end
58
55
  response.status = 200
59
56
  response.body = {
@@ -71,5 +68,4 @@ else
71
68
  end
72
69
  end
73
70
  end
74
-
75
71
  end