cocoapods 0.33.1 → 0.34.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +171 -46
- data/README.md +9 -9
- data/bin/pod +5 -5
- data/bin/sandbox-pod +2 -6
- data/lib/cocoapods.rb +4 -4
- data/lib/cocoapods/command.rb +12 -10
- data/lib/cocoapods/command/init.rb +12 -13
- data/lib/cocoapods/command/inter_process_communication.rb +6 -17
- data/lib/cocoapods/command/lib.rb +27 -24
- data/lib/cocoapods/command/list.rb +9 -9
- data/lib/cocoapods/command/outdated.rb +4 -9
- data/lib/cocoapods/command/project.rb +57 -19
- data/lib/cocoapods/command/push.rb +0 -1
- data/lib/cocoapods/command/repo.rb +14 -15
- data/lib/cocoapods/command/repo/push.rb +24 -19
- data/lib/cocoapods/command/search.rb +12 -13
- data/lib/cocoapods/command/setup.rb +10 -9
- data/lib/cocoapods/command/spec.rb +67 -63
- data/lib/cocoapods/config.rb +21 -54
- data/lib/cocoapods/downloader.rb +0 -1
- data/lib/cocoapods/executable.rb +3 -8
- data/lib/cocoapods/external_sources.rb +2 -4
- data/lib/cocoapods/external_sources/abstract_external_source.rb +15 -10
- data/lib/cocoapods/external_sources/downloader_source.rb +0 -2
- data/lib/cocoapods/external_sources/path_source.rb +1 -4
- data/lib/cocoapods/external_sources/podspec_source.rb +1 -3
- data/lib/cocoapods/gem_version.rb +1 -2
- data/lib/cocoapods/generator/acknowledgements.rb +5 -8
- data/lib/cocoapods/generator/acknowledgements/markdown.rb +5 -7
- data/lib/cocoapods/generator/acknowledgements/plist.rb +9 -10
- data/lib/cocoapods/generator/bridge_support.rb +1 -1
- data/lib/cocoapods/generator/copy_resources_script.rb +10 -14
- data/lib/cocoapods/generator/dummy_source.rb +3 -3
- data/lib/cocoapods/generator/prefix_header.rb +15 -16
- data/lib/cocoapods/generator/target_environment_header.rb +122 -36
- data/lib/cocoapods/generator/xcconfig.rb +0 -4
- data/lib/cocoapods/generator/xcconfig/aggregate_xcconfig.rb +74 -65
- data/lib/cocoapods/generator/xcconfig/private_pod_xcconfig.rb +92 -95
- data/lib/cocoapods/generator/xcconfig/public_pod_xcconfig.rb +48 -51
- data/lib/cocoapods/generator/xcconfig/xcconfig_helper.rb +10 -10
- data/lib/cocoapods/hooks/installer_representation.rb +15 -18
- data/lib/cocoapods/hooks/library_representation.rb +4 -8
- data/lib/cocoapods/hooks/pod_representation.rb +1 -5
- data/lib/cocoapods/hooks_manager.rb +63 -0
- data/lib/cocoapods/installer.rb +60 -47
- data/lib/cocoapods/installer/analyzer.rb +60 -62
- data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +5 -8
- data/lib/cocoapods/installer/file_references_installer.rb +7 -10
- data/lib/cocoapods/installer/hooks_context.rb +74 -0
- data/lib/cocoapods/installer/migrator.rb +99 -0
- data/lib/cocoapods/installer/pod_source_installer.rb +9 -29
- data/lib/cocoapods/installer/target_installer.rb +7 -17
- data/lib/cocoapods/installer/target_installer/aggregate_target_installer.rb +40 -41
- data/lib/cocoapods/installer/target_installer/pod_target_installer.rb +43 -54
- data/lib/cocoapods/installer/user_project_integrator.rb +54 -10
- data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +66 -117
- data/lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb +116 -0
- data/lib/cocoapods/open_uri.rb +1 -2
- data/lib/cocoapods/project.rb +34 -8
- data/lib/cocoapods/resolver.rb +43 -21
- data/lib/cocoapods/sandbox.rb +80 -75
- data/lib/cocoapods/sandbox/file_accessor.rb +3 -8
- data/lib/cocoapods/sandbox/headers_store.rb +6 -7
- data/lib/cocoapods/sandbox/path_list.rb +7 -10
- data/lib/cocoapods/sources_manager.rb +81 -49
- data/lib/cocoapods/target.rb +18 -12
- data/lib/cocoapods/target/aggregate_target.rb +43 -18
- data/lib/cocoapods/target/pod_target.rb +37 -4
- data/lib/cocoapods/user_interface.rb +19 -18
- data/lib/cocoapods/user_interface/error_report.rb +23 -4
- data/lib/cocoapods/validator.rb +30 -33
- metadata +100 -73
- data/lib/cocoapods/command/help.rb +0 -25
@@ -10,11 +10,11 @@ module Pod
|
|
10
10
|
|
11
11
|
def save_as(pathname)
|
12
12
|
pathname.open('w') do |source|
|
13
|
-
source.puts
|
13
|
+
source.puts '#import <Foundation/Foundation.h>'
|
14
14
|
source.puts "@interface #{class_name} : NSObject"
|
15
|
-
source.puts
|
15
|
+
source.puts '@end'
|
16
16
|
source.puts "@implementation #{class_name}"
|
17
|
-
source.puts
|
17
|
+
source.puts '@end'
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module Pod
|
2
2
|
module Generator
|
3
|
-
|
4
3
|
# Generates a prefix header file for a Pods library. The prefix header is
|
5
4
|
# generated according to the platform of the target and the pods.
|
6
5
|
#
|
@@ -8,19 +7,18 @@ module Pod
|
|
8
7
|
# `Cocoa/Cocoa.h`.
|
9
8
|
#
|
10
9
|
class PrefixHeader
|
10
|
+
# @return [Array<FileAccessor>] The file accessors for which to generate
|
11
|
+
# the prefix header.
|
12
|
+
#
|
13
|
+
attr_reader :file_accessors
|
11
14
|
|
12
15
|
# @return [Platform] the platform for which the prefix header will be
|
13
16
|
# generated.
|
14
17
|
#
|
15
|
-
attr_reader :file_accessors
|
16
18
|
attr_reader :platform
|
17
19
|
|
18
|
-
# @return [Array<
|
19
|
-
#
|
20
|
-
#
|
21
|
-
# attr_reader :consumers
|
22
|
-
|
23
|
-
# @return [Array<String>] any header to import (with quotes).
|
20
|
+
# @return [Array<String>] The list of the headers to import (with
|
21
|
+
# quotes).
|
24
22
|
#
|
25
23
|
attr_reader :imports
|
26
24
|
|
@@ -40,12 +38,14 @@ module Pod
|
|
40
38
|
# added to the top of the prefix header. For OS X `Cocoa/Cocoa.h`
|
41
39
|
# is imported.
|
42
40
|
#
|
43
|
-
# @note Only unique prefix_header_contents are added to the prefix
|
41
|
+
# @note Only unique prefix_header_contents are added to the prefix
|
42
|
+
# header.
|
44
43
|
#
|
45
44
|
# @return [String]
|
46
45
|
#
|
47
46
|
# @todo Subspecs can specify prefix header information too.
|
48
|
-
# @todo Check to see if we have a similar duplication issue with
|
47
|
+
# @todo Check to see if we have a similar duplication issue with
|
48
|
+
# file_accessor.prefix_header.
|
49
49
|
#
|
50
50
|
def generate
|
51
51
|
result = "#ifdef __OBJC__\n"
|
@@ -53,20 +53,20 @@ module Pod
|
|
53
53
|
result << "#endif\n"
|
54
54
|
|
55
55
|
imports.each do |import|
|
56
|
-
result <<
|
56
|
+
result << %(\n#import "#{import}")
|
57
57
|
end
|
58
58
|
|
59
|
-
unique_prefix_header_contents = file_accessors.
|
59
|
+
unique_prefix_header_contents = file_accessors.map do |file_accessor|
|
60
60
|
file_accessor.spec_consumer.prefix_header_contents
|
61
61
|
end.compact.uniq
|
62
|
-
|
62
|
+
|
63
63
|
result << "\n"
|
64
|
-
|
64
|
+
|
65
65
|
unique_prefix_header_contents.each do |prefix_header_contents|
|
66
66
|
result << prefix_header_contents
|
67
67
|
result << "\n"
|
68
68
|
end
|
69
|
-
|
69
|
+
|
70
70
|
file_accessors.each do |file_accessor|
|
71
71
|
if prefix_header = file_accessor.prefix_header
|
72
72
|
result << Pathname(prefix_header).read
|
@@ -85,7 +85,6 @@ module Pod
|
|
85
85
|
def save_as(path)
|
86
86
|
path.open('w') { |header| header.write(generate) }
|
87
87
|
end
|
88
|
-
|
89
88
|
end
|
90
89
|
end
|
91
90
|
end
|
@@ -1,6 +1,7 @@
|
|
1
|
+
require 'active_support/core_ext/string/strip'
|
2
|
+
|
1
3
|
module Pod
|
2
4
|
module Generator
|
3
|
-
|
4
5
|
# Generates a header which allows to inspect at compile time the installed
|
5
6
|
# pods and the installed specifications of a pod.
|
6
7
|
#
|
@@ -22,15 +23,15 @@ module Pod
|
|
22
23
|
# #endif
|
23
24
|
#
|
24
25
|
class TargetEnvironmentHeader
|
25
|
-
|
26
|
-
#
|
26
|
+
# @return [Hash{String => LocalPod}] the specifications installed for
|
27
|
+
# the target by build configuration name.
|
27
28
|
#
|
28
|
-
attr_reader :
|
29
|
+
attr_reader :specs_by_configuration
|
29
30
|
|
30
|
-
# @param [Array<
|
31
|
+
# @param [Array<Specification>] pods @see pods
|
31
32
|
#
|
32
|
-
def initialize(
|
33
|
-
@
|
33
|
+
def initialize(specs_by_configuration)
|
34
|
+
@specs_by_configuration = specs_by_configuration
|
34
35
|
end
|
35
36
|
|
36
37
|
# Generates and saves the file.
|
@@ -40,47 +41,132 @@ module Pod
|
|
40
41
|
#
|
41
42
|
# @return [void]
|
42
43
|
#
|
43
|
-
def
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
spec_name = safe_spec_name(spec.name)
|
55
|
-
source.puts "// #{spec.name}"
|
56
|
-
source.puts "#define COCOAPODS_POD_AVAILABLE_#{spec_name}"
|
57
|
-
if spec.version.semantic?
|
58
|
-
source.puts "#define COCOAPODS_VERSION_MAJOR_#{spec_name} #{spec.version.major}"
|
59
|
-
source.puts "#define COCOAPODS_VERSION_MINOR_#{spec_name} #{spec.version.minor}"
|
60
|
-
source.puts "#define COCOAPODS_VERSION_PATCH_#{spec_name} #{spec.version.patch}"
|
61
|
-
else
|
62
|
-
source.puts "// This library does not follow semantic-versioning,"
|
63
|
-
source.puts "// so we were not able to define version macros."
|
64
|
-
source.puts "// Please contact the author."
|
65
|
-
source.puts "// Version: #{spec.version}."
|
66
|
-
end
|
67
|
-
source.puts
|
68
|
-
end
|
44
|
+
def generate
|
45
|
+
result = "\n#{notice}\n\n"
|
46
|
+
common_specs = common_specs(specs_by_configuration)
|
47
|
+
common_specs.each { |spec| result << spec_defines(spec) }
|
48
|
+
|
49
|
+
specs_by_config = specs_scoped_by_configuration(common_specs, specs_by_configuration)
|
50
|
+
specs_by_config.each do |config, specs|
|
51
|
+
result << "// #{config} build configuration\n"
|
52
|
+
result << "#ifdef #{config.gsub(' ', '_').upcase}\n\n"
|
53
|
+
specs.each { |spec| result << spec_defines(spec, 1) }
|
54
|
+
result << "#endif\n"
|
69
55
|
end
|
56
|
+
result
|
70
57
|
end
|
71
58
|
|
72
|
-
|
59
|
+
def save_as(path)
|
60
|
+
path.open('w') { |header| header.write(generate) }
|
61
|
+
end
|
73
62
|
|
74
63
|
private
|
75
64
|
|
76
65
|
# !@group Private Helpers
|
66
|
+
#-----------------------------------------------------------------------#
|
77
67
|
|
68
|
+
# @return [Array<Specification>] The list of the specifications present
|
69
|
+
# in all build configurations sorted by name.
|
70
|
+
#
|
71
|
+
# @param [Hash{String => Array<Specification>}] specs_by_configuration
|
72
|
+
# The specs grouped by build configuration.
|
73
|
+
#
|
74
|
+
def common_specs(specs_by_configuration)
|
75
|
+
result = specs_by_configuration.values.flatten.uniq
|
76
|
+
specs_by_configuration.values.each do |configuration_specs|
|
77
|
+
result = result & configuration_specs
|
78
|
+
end
|
79
|
+
result.sort_by(&:name)
|
80
|
+
end
|
81
|
+
|
82
|
+
# @return [Hash{String => Array<Specification>}] The list of the
|
83
|
+
# specifications not present in all build configurations sorted
|
84
|
+
# by name and grouped by build configuration name.
|
85
|
+
#
|
86
|
+
# @param [Hash{String => Array<Specification>}] specs_by_configuration
|
87
|
+
# The specs grouped by build configuration.
|
88
|
+
#
|
89
|
+
def specs_scoped_by_configuration(common_specs, specs_by_configuration)
|
90
|
+
result = {}
|
91
|
+
specs_by_configuration.each do |configuration, all_specs|
|
92
|
+
specs = all_specs.sort_by(&:name) - common_specs
|
93
|
+
result[configuration] = specs unless specs.empty?
|
94
|
+
end
|
95
|
+
result
|
96
|
+
end
|
97
|
+
|
98
|
+
# @return The sanitized name of a specification to make it suitable to be
|
99
|
+
# used as part of an identifier of a define statement.
|
100
|
+
#
|
101
|
+
# @param [String] spec_name
|
102
|
+
# The name of the spec.
|
103
|
+
#
|
78
104
|
def safe_spec_name(spec_name)
|
79
|
-
spec_name.gsub(/[^\w]/,'_')
|
105
|
+
spec_name.gsub(/[^\w]/, '_')
|
80
106
|
end
|
81
107
|
|
82
|
-
|
108
|
+
# @return [String]
|
109
|
+
#
|
110
|
+
def notice
|
111
|
+
<<-DOC.strip_heredoc
|
112
|
+
// To check if a library is compiled with CocoaPods you
|
113
|
+
// can use the `COCOAPODS` macro definition which is
|
114
|
+
// defined in the xcconfigs so it is available in
|
115
|
+
// headers also when they are imported in the client
|
116
|
+
// project.
|
117
|
+
DOC
|
118
|
+
end
|
119
|
+
|
120
|
+
# @return [String]
|
121
|
+
#
|
122
|
+
def spec_defines(spec, indent_count = 0)
|
123
|
+
spec_name = safe_spec_name(spec.name)
|
124
|
+
result = "// #{spec.name}\n"
|
125
|
+
result << "#define COCOAPODS_POD_AVAILABLE_#{spec_name}\n"
|
126
|
+
if spec.version.semantic?
|
127
|
+
result << semantic_version_defines(spec)
|
128
|
+
else
|
129
|
+
result << non_semantic_version_notice(spec)
|
130
|
+
end
|
131
|
+
result << "\n"
|
132
|
+
indent(result, indent_count)
|
133
|
+
end
|
83
134
|
|
135
|
+
def indent(string, indent_count)
|
136
|
+
indent = ' ' * (indent_count * 2)
|
137
|
+
lines = string.lines.map do |line|
|
138
|
+
if line == "\n"
|
139
|
+
line
|
140
|
+
else
|
141
|
+
"#{indent}#{line}"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
lines.join
|
145
|
+
end
|
146
|
+
|
147
|
+
# @return [String]
|
148
|
+
#
|
149
|
+
def semantic_version_defines(spec)
|
150
|
+
spec_name = safe_spec_name(spec.name)
|
151
|
+
<<-DOC.strip_heredoc
|
152
|
+
#define COCOAPODS_VERSION_MAJOR_#{spec_name} #{spec.version.major}
|
153
|
+
#define COCOAPODS_VERSION_MINOR_#{spec_name} #{spec.version.minor}
|
154
|
+
#define COCOAPODS_VERSION_PATCH_#{spec_name} #{spec.version.patch}
|
155
|
+
DOC
|
156
|
+
end
|
157
|
+
|
158
|
+
# @return [String]
|
159
|
+
#
|
160
|
+
def non_semantic_version_notice(spec)
|
161
|
+
<<-DOC.strip_heredoc
|
162
|
+
// This library does not follow semantic-versioning,
|
163
|
+
// so we were not able to define version macros.
|
164
|
+
// Please contact the author.
|
165
|
+
// Version: #{spec.version}.
|
166
|
+
DOC
|
167
|
+
end
|
168
|
+
|
169
|
+
#-----------------------------------------------------------------------#
|
84
170
|
end
|
85
171
|
end
|
86
172
|
end
|
@@ -1,18 +1,14 @@
|
|
1
1
|
module Pod
|
2
2
|
module Generator
|
3
|
-
|
4
3
|
# Generates Xcode configuration files. A configuration file is generated
|
5
4
|
# for each Pod and for each Pod target definition. The aggregates the
|
6
5
|
# configurations of the Pods and define target specific settings.
|
7
6
|
#
|
8
7
|
module XCConfig
|
9
|
-
|
10
8
|
autoload :AggregateXCConfig, 'cocoapods/generator/xcconfig/aggregate_xcconfig'
|
11
9
|
autoload :PublicPodXCConfig, 'cocoapods/generator/xcconfig/public_pod_xcconfig'
|
12
10
|
autoload :PrivatePodXCConfig, 'cocoapods/generator/xcconfig/private_pod_xcconfig'
|
13
11
|
autoload :XCConfigHelper, 'cocoapods/generator/xcconfig/xcconfig_helper'
|
14
|
-
|
15
12
|
end
|
16
13
|
end
|
17
14
|
end
|
18
|
-
|
@@ -1,82 +1,91 @@
|
|
1
1
|
module Pod
|
2
2
|
module Generator
|
3
3
|
module XCConfig
|
4
|
-
|
5
|
-
# Generates the xcconfigs for the aggregate targets.
|
6
|
-
#
|
7
|
-
class AggregateXCConfig
|
8
|
-
|
9
|
-
# @return [Target] the target represented by this xcconfig.
|
4
|
+
# Generates the xcconfigs for the aggregate targets.
|
10
5
|
#
|
11
|
-
|
6
|
+
class AggregateXCConfig
|
7
|
+
# @return [Target] the target represented by this xcconfig.
|
8
|
+
#
|
9
|
+
attr_reader :target
|
12
10
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
11
|
+
# @param [Target] target @see target
|
12
|
+
#
|
13
|
+
# @param [String] configuration_name
|
14
|
+
# The name of the build configuration to generate this xcconfig
|
15
|
+
# for.
|
16
|
+
#
|
17
|
+
def initialize(target, configuration_name)
|
18
|
+
@target = target
|
19
|
+
@configuration_name = configuration_name
|
20
|
+
end
|
18
21
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
+
# @return [Xcodeproj::Config] The generated xcconfig.
|
23
|
+
#
|
24
|
+
attr_reader :xcconfig
|
22
25
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
26
|
+
# Generates and saves the xcconfig to the given path.
|
27
|
+
#
|
28
|
+
# @param [Pathname] path
|
29
|
+
# the path where the prefix header should be stored.
|
30
|
+
#
|
31
|
+
# @return [void]
|
32
|
+
#
|
33
|
+
def save_as(path)
|
34
|
+
generate.save_as(path)
|
35
|
+
end
|
33
36
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
37
|
+
# Generates the xcconfig.
|
38
|
+
#
|
39
|
+
# @note The xcconfig file for a Pods integration target includes the
|
40
|
+
# namespaced xcconfig files for each spec target dependency.
|
41
|
+
# Each namespaced configuration value is merged into the Pod
|
42
|
+
# xcconfig file.
|
43
|
+
#
|
44
|
+
# @todo This doesn't include the specs xcconfigs anymore and now the
|
45
|
+
# logic is duplicated.
|
46
|
+
#
|
47
|
+
# @return [Xcodeproj::Config]
|
48
|
+
#
|
49
|
+
def generate
|
50
|
+
header_search_path_flags = target.sandbox.public_headers.search_paths
|
51
|
+
@xcconfig = Xcodeproj::Config.new(
|
52
|
+
'OTHER_LDFLAGS' => XCConfigHelper.default_ld_flags(target),
|
53
|
+
'HEADER_SEARCH_PATHS' => XCConfigHelper.quote(target.sandbox.public_headers.search_paths),
|
54
|
+
'PODS_ROOT' => target.relative_pods_root,
|
55
|
+
'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) COCOAPODS=1',
|
56
|
+
'OTHER_CFLAGS' => '$(inherited) ' + XCConfigHelper.quote(header_search_path_flags, '-isystem')
|
57
|
+
)
|
55
58
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
XCConfigHelper.
|
61
|
-
|
62
|
-
|
63
|
-
|
59
|
+
target.pod_targets.each do |pod_target|
|
60
|
+
next unless pod_target.include_in_build_config?(@configuration_name)
|
61
|
+
|
62
|
+
pod_target.file_accessors.each do |file_accessor|
|
63
|
+
XCConfigHelper.add_spec_build_settings_to_xcconfig(file_accessor.spec_consumer, @xcconfig)
|
64
|
+
file_accessor.vendored_frameworks.each do |vendored_framework|
|
65
|
+
XCConfigHelper.add_framework_build_settings(vendored_framework, @xcconfig, target.sandbox.root)
|
66
|
+
end
|
67
|
+
file_accessor.vendored_libraries.each do |vendored_library|
|
68
|
+
XCConfigHelper.add_library_build_settings(vendored_library, @xcconfig, target.sandbox.root)
|
69
|
+
end
|
64
70
|
end
|
65
|
-
end
|
66
|
-
end
|
67
71
|
|
68
|
-
|
69
|
-
|
70
|
-
#
|
71
|
-
# See https://github.com/CocoaPods/CocoaPods/issues/1216
|
72
|
-
@xcconfig.attributes.delete('USE_HEADERMAP')
|
72
|
+
# Add pod static lib to list of libraries that are to be linked with
|
73
|
+
# the user’s project.
|
73
74
|
|
74
|
-
|
75
|
-
|
75
|
+
@xcconfig.merge!('OTHER_LDFLAGS' => %(-l "#{pod_target.name}"))
|
76
|
+
end
|
77
|
+
|
78
|
+
# TODO Need to decide how we are going to ensure settings like these
|
79
|
+
# are always excluded from the user's project.
|
80
|
+
#
|
81
|
+
# See https://github.com/CocoaPods/CocoaPods/issues/1216
|
82
|
+
@xcconfig.attributes.delete('USE_HEADERMAP')
|
76
83
|
|
77
|
-
|
84
|
+
@xcconfig
|
85
|
+
end
|
78
86
|
|
79
|
-
|
87
|
+
#---------------------------------------------------------------------#
|
88
|
+
end
|
80
89
|
end
|
81
90
|
end
|
82
91
|
end
|