qti 0.9.1 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/qti/assessment_item_exporter.rb +1 -1
- data/lib/qti/content_packaging/assessment_item.rb +1 -1
- data/lib/qti/content_packaging/assessment_test.rb +2 -2
- data/lib/qti/content_packaging/choice_interaction.rb +1 -1
- data/lib/qti/models/base.rb +13 -5
- data/lib/qti/models/manifest.rb +21 -7
- data/lib/qti/v1/models/assessment.rb +3 -1
- data/lib/qti/v1/models/assessment_item.rb +13 -5
- data/lib/qti/v1/models/choices/fill_blank_choice.rb +1 -1
- data/lib/qti/v1/models/choices/logical_identifier_choice.rb +1 -1
- data/lib/qti/v1/models/interactions/base_interaction.rb +1 -1
- data/lib/qti/v1/models/interactions/choice_interaction.rb +19 -5
- data/lib/qti/v2/models/assessment_item.rb +23 -6
- data/lib/qti/v2/models/assessment_test.rb +3 -1
- data/lib/qti/v2/models/choices/gap_match_choice.rb +1 -1
- data/lib/qti/v2/models/choices/simple_choice.rb +1 -1
- data/lib/qti/v2/models/interactions/base_interaction.rb +1 -1
- data/lib/qti/v2/models/interactions/gap_match_interaction.rb +16 -7
- data/lib/qti/version.rb +1 -1
- data/spec/lib/qti/v1/models/interactions/choice_interaction_spec.rb +9 -2
- data/spec/lib/qti/v2/models/assessment_item_spec.rb +12 -0
- data/spec/lib/qti/v2/models/assessment_test_spec.rb +9 -2
- data/spec/lib/qti_spec.rb +1 -0
- data/spec/lib/stupid.xml +128 -0
- metadata +19 -17
- data/spec/gemfiles/nokogiri-1.6.gemfile.lock +0 -126
- data/spec/gemfiles/nokogiri-1.8.gemfile.lock +0 -126
- data/spec/gemfiles/rails-4.2.gemfile.lock +0 -203
- data/spec/gemfiles/rails-5.0.gemfile.lock +0 -209
- data/spec/gemfiles/rails-5.1.gemfile.lock +0 -209
- data/spec/gemfiles/sanitize-4.2.gemfile.lock +0 -126
- data/spec/gemfiles/sanitize-4.5.gemfile.lock +0 -126
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9278a5814a878f23f53159c3adb0c64e7d7a8e69
|
4
|
+
data.tar.gz: 8892e930ffbf68ef68b5f08fddd5ed3fa63f34da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 25f42764b0ac0109aa2ab6edf7e3e814fd4150b94b195684f856acaa6faaa859712287a6262141352456b1e341e6d1caef0e037fdfce476d2742cc67d53f3203
|
7
|
+
data.tar.gz: e3cda7d07238a30879125895ef9b73bb1283d2776803ace6489e5226e0ddd736ebf09321e8f65a7fe5cb01a1783ba8a01d0ddb9476be4724b8b34a79d07146b2
|
@@ -4,7 +4,7 @@ module Qti
|
|
4
4
|
attribute :identifier, Types::Strict::String
|
5
5
|
attribute :title, Types::Strict::String
|
6
6
|
attribute :interaction, ContentPackaging::ChoiceInteraction
|
7
|
-
attribute :response, Types::Strict::Array.
|
7
|
+
attribute :response, Types::Strict::Array.of(String) | Types::Strict::String
|
8
8
|
end
|
9
9
|
end
|
10
10
|
end
|
@@ -3,8 +3,8 @@ module Qti
|
|
3
3
|
class AssessmentTest < Dry::Struct
|
4
4
|
attribute :identifier, Types::Strict::String
|
5
5
|
attribute :title, Types::Strict::String
|
6
|
-
attribute :items, Types::Strict::Array.
|
7
|
-
attribute :outcome_declarations, Types::Strict::Array.
|
6
|
+
attribute :items, Types::Strict::Array.of(ContentPackaging::AssessmentItem)
|
7
|
+
attribute :outcome_declarations, Types::Strict::Array.of(ContentPackaging::OutcomeDeclaration)
|
8
8
|
end
|
9
9
|
end
|
10
10
|
end
|
@@ -6,7 +6,7 @@ module Qti
|
|
6
6
|
attribute :prompt, Types::Strict::String
|
7
7
|
attribute :shuffle, Types::Strict::Bool.default(false)
|
8
8
|
attribute :maxChoices, Types::Coercible::Int
|
9
|
-
attribute :choices, Types::Strict::Array.
|
9
|
+
attribute :choices, Types::Strict::Array.of(ContentPackaging::SimpleChoice)
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
data/lib/qti/models/base.rb
CHANGED
@@ -10,6 +10,7 @@ module Qti
|
|
10
10
|
module Models
|
11
11
|
class Base
|
12
12
|
attr_reader :doc, :path, :package_root
|
13
|
+
attr_accessor :manifest
|
13
14
|
|
14
15
|
ELEMENTS_REMAP = {
|
15
16
|
'prompt' => 'div',
|
@@ -58,7 +59,7 @@ module Qti
|
|
58
59
|
|
59
60
|
def initialize(path:, package_root: nil, html: false)
|
60
61
|
@path = path
|
61
|
-
|
62
|
+
self.package_root = package_root || File.dirname(path)
|
62
63
|
@doc = html ? parse_html(File.read(path)) : parse_xml(File.read(path))
|
63
64
|
raise ArgumentError unless @doc
|
64
65
|
end
|
@@ -89,20 +90,27 @@ module Qti
|
|
89
90
|
if @package_root.nil?
|
90
91
|
raise Qti::ParseError, "Potentially unsafe href '#{href}'" if href.split('/').include?('..')
|
91
92
|
else
|
92
|
-
|
93
|
+
unless Pathname.new(path).cleanpath.to_s.start_with?(@package_root)
|
94
|
+
raise Qti::ParseError, "Unsafe href '#{href}'"
|
95
|
+
end
|
93
96
|
end
|
94
97
|
path
|
95
98
|
end
|
96
99
|
|
97
100
|
protected
|
98
101
|
|
99
|
-
def
|
102
|
+
def package_root=(package_root)
|
100
103
|
@package_root = package_root
|
101
104
|
return unless @package_root
|
102
105
|
@package_root = Pathname.new(@package_root).cleanpath.to_s + '/'
|
103
106
|
end
|
104
107
|
|
105
|
-
def
|
108
|
+
def relative_path
|
109
|
+
return nil if @path.nil? || @package_root.nil?
|
110
|
+
@path.sub(/\A#{Regexp.quote(@package_root)}/, '')
|
111
|
+
end
|
112
|
+
|
113
|
+
def copy_paths_from_item(other_item)
|
106
114
|
@package_root = other_item.package_root
|
107
115
|
@path = other_item.path
|
108
116
|
end
|
@@ -111,7 +119,7 @@ module Qti
|
|
111
119
|
path = remap_href_path(node[:data])
|
112
120
|
if path
|
113
121
|
case node[:type]
|
114
|
-
when
|
122
|
+
when %r{^image\/}
|
115
123
|
return replace_with_image(node, node[:data])
|
116
124
|
when 'text/html'
|
117
125
|
return replace_with_html(node, path)
|
data/lib/qti/models/manifest.rb
CHANGED
@@ -4,19 +4,27 @@ module Qti
|
|
4
4
|
module Models
|
5
5
|
class Manifest < Qti::Models::Base
|
6
6
|
def assessment_test
|
7
|
-
qti_2_x_href || qti_1_href || qti_2_non_assessment_href || unknown_type
|
7
|
+
test = qti_2_x_href || qti_1_href || qti_2_non_assessment_href || unknown_type
|
8
|
+
test.manifest = self
|
9
|
+
test
|
8
10
|
end
|
9
11
|
|
10
12
|
def qti_1_href
|
11
|
-
test_path =
|
12
|
-
|
13
|
-
|
13
|
+
test_path = xmlns_resource("[@type='imsqti_xmlv1p2']/@href") ||
|
14
|
+
xmlns_resource("[@type='imsqti_xmlv1p2']/xmlns:file/@href")
|
15
|
+
return unless test_path
|
16
|
+
Qti::V1::Models::Assessment.from_path!(
|
17
|
+
remap_href_path(test_path), @package_root
|
18
|
+
)
|
14
19
|
end
|
15
20
|
|
16
21
|
def qti_2_x_href
|
17
|
-
test_path =
|
18
|
-
|
19
|
-
|
22
|
+
test_path = xmlns_resource("[@type='imsqti_test_xmlv2p1']/@href") ||
|
23
|
+
xmlns_resource("[@type='imsqti_test_xmlv2p2']/@href")
|
24
|
+
return unless test_path
|
25
|
+
Qti::V2::Models::AssessmentTest.from_path!(
|
26
|
+
remap_href_path(test_path), @package_root
|
27
|
+
)
|
20
28
|
end
|
21
29
|
|
22
30
|
def qti_2_non_assessment_href
|
@@ -27,6 +35,12 @@ module Qti
|
|
27
35
|
def unknown_type
|
28
36
|
raise Qti::UnsupportedSchema, 'Unsupported QTI version'
|
29
37
|
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def xmlns_resource(type)
|
42
|
+
xpath_with_single_check("//xmlns:resources/xmlns:resource#{type}")&.content
|
43
|
+
end
|
30
44
|
end
|
31
45
|
end
|
32
46
|
end
|
@@ -13,7 +13,9 @@ module Qti
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def create_assessment_item(assessment_item)
|
16
|
-
Qti::V1::Models::AssessmentItem.new(assessment_item, @package_root)
|
16
|
+
item = Qti::V1::Models::AssessmentItem.new(assessment_item, @package_root)
|
17
|
+
item.manifest = manifest
|
18
|
+
item
|
17
19
|
end
|
18
20
|
|
19
21
|
def stimulus_ref(_ref)
|
@@ -10,7 +10,7 @@ module Qti
|
|
10
10
|
def initialize(item, package_root = nil)
|
11
11
|
@doc = item
|
12
12
|
@path = item.document.url
|
13
|
-
|
13
|
+
self.package_root = package_root
|
14
14
|
end
|
15
15
|
|
16
16
|
def item_body
|
@@ -34,7 +34,7 @@ module Qti
|
|
34
34
|
@doc.at_xpath('.//xmlns:qtimetadata')&.children
|
35
35
|
end
|
36
36
|
|
37
|
-
def
|
37
|
+
def points_possible_qti_metadata?
|
38
38
|
if @doc.at_xpath('.//xmlns:qtimetadata').present?
|
39
39
|
points_possible_label = qti_metadata_children.children.find { |node| node.text == 'points_possible' }
|
40
40
|
points_possible_label.present?
|
@@ -43,11 +43,19 @@ module Qti
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
+
# @deprecated Please use {#points_possible_qti_metadata?} instead
|
47
|
+
def has_points_possible_qti_metadata? # rubocop:disable Naming/PredicateName
|
48
|
+
warn "DEPRECATED: '#{__method__}' is renamed to 'points_possible_qti_metadata?'."
|
49
|
+
points_possible_qti_metadata?
|
50
|
+
end
|
51
|
+
|
46
52
|
def points_possible
|
47
53
|
@points_possible ||= begin
|
48
|
-
if
|
49
|
-
points_possible_label = qti_metadata_children.children.find
|
50
|
-
|
54
|
+
if points_possible_qti_metadata?
|
55
|
+
points_possible_label = qti_metadata_children.children.find do |node|
|
56
|
+
node.text == 'points_possible'
|
57
|
+
end
|
58
|
+
points_possible_label.next.text
|
51
59
|
else
|
52
60
|
decvar_maxvalue
|
53
61
|
end
|
@@ -21,12 +21,9 @@ module Qti
|
|
21
21
|
def scoring_data_structs
|
22
22
|
choice_nodes = node.xpath('.//xmlns:respcondition')
|
23
23
|
if choice_nodes.at_xpath('.//xmlns:and').present?
|
24
|
-
|
25
|
-
answer_choices.children.filter('not').each(&:remove)
|
26
|
-
answer_choices.children.map { |value_node| ScoringData.new(value_node.content, rcardinality) }
|
24
|
+
scoring_data_condition(choice_nodes)
|
27
25
|
else
|
28
|
-
|
29
|
-
set_var_nodes.map { |value_node| ScoringData.new(value_node.at_xpath('.//xmlns:varequal').content, rcardinality) }
|
26
|
+
scoring_data(choice_nodes)
|
30
27
|
end
|
31
28
|
end
|
32
29
|
|
@@ -35,6 +32,23 @@ module Qti
|
|
35
32
|
def answer_nodes
|
36
33
|
node.xpath('.//xmlns:response_label')
|
37
34
|
end
|
35
|
+
|
36
|
+
def scoring_data_condition(choice_nodes)
|
37
|
+
answer_choices = choice_nodes.at_xpath('.//xmlns:and')
|
38
|
+
answer_choices.children.filter('not').each(&:remove)
|
39
|
+
answer_choices.children.map do |value_node|
|
40
|
+
ScoringData.new(value_node.content, rcardinality)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def scoring_data(choice_nodes)
|
45
|
+
set_var_nodes = choice_nodes.select do |choice_node|
|
46
|
+
choice_node.at_xpath('.//xmlns:setvar')&.content&.to_f&.positive?
|
47
|
+
end
|
48
|
+
set_var_nodes.map do |value_node|
|
49
|
+
ScoringData.new(value_node.at_xpath('.//xmlns:varequal').content, rcardinality)
|
50
|
+
end
|
51
|
+
end
|
38
52
|
end
|
39
53
|
end
|
40
54
|
end
|
@@ -12,12 +12,7 @@ module Qti
|
|
12
12
|
node = item_body_node.dup
|
13
13
|
# ensure a prompt is carried into the html
|
14
14
|
prompt = node.at_xpath('//xmlns:prompt')
|
15
|
-
|
16
|
-
# Filter undesired interaction nodes out of the list (need to make this a deep traversal)
|
17
|
-
node.children.filter(INTERACTION_ELEMENTS_CSS).map(&:unlink)
|
18
|
-
# Filter out rubrics
|
19
|
-
node.children.filter('rubricBlock').map(&:unlink)
|
20
|
-
|
15
|
+
filter_item_body(node)
|
21
16
|
node.add_child(prompt) if prompt&.parent && prompt.parent != node
|
22
17
|
sanitize_content!(node.to_html)
|
23
18
|
end
|
@@ -54,6 +49,28 @@ module Qti
|
|
54
49
|
def item_body_node
|
55
50
|
@item_body_node ||= xpath_with_single_check('//xmlns:itemBody')
|
56
51
|
end
|
52
|
+
|
53
|
+
def filter_item_body(node)
|
54
|
+
# Filter undesired interaction nodes out of the list (need to make this a deep traversal)
|
55
|
+
node.children.filter(INTERACTION_ELEMENTS_CSS).map(&:unlink)
|
56
|
+
# Filter out rubrics
|
57
|
+
node.children.filter('rubricBlock').map(&:unlink)
|
58
|
+
# Filter out stimulus passages (these will be handled separately)
|
59
|
+
filter_stimulus_passages!(node)
|
60
|
+
end
|
61
|
+
|
62
|
+
def dependency_hrefs
|
63
|
+
return [] unless manifest
|
64
|
+
manifest.doc.xpath("//xmlns:resource[@href='#{relative_path}']/xmlns:dependency/@identifierref").map do |id|
|
65
|
+
manifest.xpath_with_single_check("//xmlns:resource[@identifier='#{id}']/@href")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def filter_stimulus_passages!(node)
|
70
|
+
dependency_hrefs.each do |href|
|
71
|
+
node.at_css("object[type='text/html'][data='#{href}']").try(:unlink)
|
72
|
+
end
|
73
|
+
end
|
57
74
|
end
|
58
75
|
end
|
59
76
|
end
|
@@ -26,7 +26,9 @@ module Qti
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def create_assessment_item(assessment_item_ref)
|
29
|
-
Qti::V2::Models::AssessmentItem.from_path!(assessment_item_ref, @package_root)
|
29
|
+
item = Qti::V2::Models::AssessmentItem.from_path!(assessment_item_ref, @package_root)
|
30
|
+
item.manifest = manifest
|
31
|
+
item
|
30
32
|
end
|
31
33
|
|
32
34
|
def stimulus_ref(_ref)
|
@@ -85,16 +85,11 @@ module Qti
|
|
85
85
|
end
|
86
86
|
|
87
87
|
def scoring_data_structs
|
88
|
-
|
89
|
-
value.content.split
|
90
|
-
end
|
91
|
-
question_response_pairs.map!(&:reverse)
|
92
|
-
question_response_id_mapping = Hash[question_response_pairs]
|
88
|
+
mapping = question_response_id_mapping
|
93
89
|
answer_nodes.map do |value_node|
|
94
90
|
node_id = value_node.attributes['identifier']&.value
|
95
|
-
answer_choice = choices.find { |choice| choice.attributes['identifier']&.value == question_response_id_mapping[node_id] }
|
96
91
|
ScoringData.new(
|
97
|
-
answer_choice.content,
|
92
|
+
answer_choice(choices, mapping[node_id]).content,
|
98
93
|
'directedPair',
|
99
94
|
id: node_id,
|
100
95
|
case: false
|
@@ -111,6 +106,20 @@ module Qti
|
|
111
106
|
def answer_nodes
|
112
107
|
@node.xpath('.//xmlns:gap')
|
113
108
|
end
|
109
|
+
|
110
|
+
def answer_choice(choices, response)
|
111
|
+
choices.find do |choice|
|
112
|
+
choice.attributes['identifier']&.value == response
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def question_response_id_mapping
|
117
|
+
question_response_pairs = node.xpath('.//xmlns:correctResponse//xmlns:value').map do |value|
|
118
|
+
value.content.split
|
119
|
+
end
|
120
|
+
question_response_pairs.map!(&:reverse)
|
121
|
+
Hash[question_response_pairs]
|
122
|
+
end
|
114
123
|
end
|
115
124
|
end
|
116
125
|
end
|
data/lib/qti/version.rb
CHANGED
@@ -15,7 +15,8 @@ describe Qti::V1::Models::Interactions::ChoiceInteraction do
|
|
15
15
|
shared_examples_for 'answers' do
|
16
16
|
it 'returns the answers' do
|
17
17
|
expect(loaded_class.answers.count).to eq answer_choices_count
|
18
|
-
expect(loaded_class.answers.first)
|
18
|
+
expect(loaded_class.answers.first)
|
19
|
+
.to be_an_instance_of(Qti::V1::Models::Choices::LogicalIdentifierChoice)
|
19
20
|
end
|
20
21
|
end
|
21
22
|
|
@@ -54,7 +55,13 @@ describe Qti::V1::Models::Interactions::ChoiceInteraction do
|
|
54
55
|
|
55
56
|
context 'multiple respconditions with empty setvars' do
|
56
57
|
let(:fixtures_path) { File.join('spec', 'fixtures', 'test_with_comments') }
|
57
|
-
let(:file_path)
|
58
|
+
let(:file_path) do
|
59
|
+
File.join(
|
60
|
+
fixtures_path,
|
61
|
+
'i6c88aaf29feba2ffa58a487a20665394',
|
62
|
+
'i6c88aaf29feba2ffa58a487a20665394.xml'
|
63
|
+
)
|
64
|
+
end
|
58
65
|
|
59
66
|
it 'loads the items' do
|
60
67
|
expect(loaded_class.scoring_data_structs.count).to eq 1
|
@@ -77,4 +77,16 @@ describe Qti::V2::Models::AssessmentItem do
|
|
77
77
|
end
|
78
78
|
end
|
79
79
|
end
|
80
|
+
|
81
|
+
context 'stimulus passages' do
|
82
|
+
let(:file_path) { File.join('spec', 'fixtures', 'no_assessment_XML') }
|
83
|
+
let(:importer) { Qti::Importer.new(file_path) }
|
84
|
+
let(:test_object) { importer.test_object }
|
85
|
+
let(:item_ref) { File.join(file_path, 'a4f3621a-195c-4847-a72c-69388250a078.xml') }
|
86
|
+
|
87
|
+
it 'removes the passage from the item_body' do
|
88
|
+
item = test_object.create_assessment_item(item_ref)
|
89
|
+
expect(item.item_body).not_to include '¡El equipo de hockey te necesita!'
|
90
|
+
end
|
91
|
+
end
|
80
92
|
end
|
@@ -35,7 +35,11 @@ describe Qti::V2::Models::AssessmentTest do
|
|
35
35
|
test_files = Dir.glob(File.join(fixtures_path, 'tests', 'tests', 'rtest[0-9][0-9].xml'))
|
36
36
|
test_files << File.join(fixtures_path, 'tests', 'tests', 'complete.xml')
|
37
37
|
test_files << File.join(fixtures_path, 'tests', 'feedbackTest', 'assessment.xml')
|
38
|
-
test_files << File.join(
|
38
|
+
test_files << File.join(
|
39
|
+
fixtures_path, 'tests',
|
40
|
+
'interactionmix_saxony_v3',
|
41
|
+
'InteractionMixSachsen_1901710679.xml'
|
42
|
+
)
|
39
43
|
test_files.each do |file|
|
40
44
|
context File.basename(file) do
|
41
45
|
let(:loaded_class) { described_class.from_path!(file) }
|
@@ -77,7 +81,10 @@ describe Qti::V2::Models::AssessmentTest do
|
|
77
81
|
let(:loaded_class) { described_class.from_path!(path) }
|
78
82
|
|
79
83
|
it 'creates a stimulus from a given file' do
|
80
|
-
stimulus_path = File.join(
|
84
|
+
stimulus_path = File.join(
|
85
|
+
fixtures_path, 'no_assessment_XML',
|
86
|
+
'passages', '0cfd5cf7-2c91-4b35-a57a-9f5d1709f68f.html'
|
87
|
+
)
|
81
88
|
stimulus = loaded_class.create_stimulus(stimulus_path)
|
82
89
|
expect(stimulus.title).to eq '¡El equipo de hockey te necesita!'
|
83
90
|
end
|
data/spec/lib/qti_spec.rb
CHANGED
data/spec/lib/stupid.xml
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<manifest xmlns="http://www.imsglobal.org/xsd/imscp_v1p1" identifier="Manifest-d1042982-b88a-4c04-a6e0-9bb718b41178"
|
3
|
+
xmlns="http://www.imsglobal.org/xsd/imscp_v1p1" xmlns:imsmd="http://www.imsglobal.org/xsd/imsmd_v1p2"
|
4
|
+
xmlns:imsqti="http://www.imsglobal.org/xsd/imsqti_v2p1">
|
5
|
+
<organizations/>
|
6
|
+
<metadata>
|
7
|
+
<schema>IMS Content</schema>
|
8
|
+
<schemaversion>2.1</schemaversion>
|
9
|
+
<imsmd:lom xmlns:imsmd="http://www.imsglobal.org/xsd/imsmd_v1p2">
|
10
|
+
<imsmd:general>
|
11
|
+
<imsmd:title>
|
12
|
+
<imsmd:langstring>Assignment test? Worth Points Question Pool 1</imsmd:langstring>
|
13
|
+
</imsmd:title>
|
14
|
+
</imsmd:general>
|
15
|
+
</imsmd:lom>
|
16
|
+
</metadata>
|
17
|
+
<resources>
|
18
|
+
<resource href="1009/question4928.xml" identifier="1788:4928" type="imsqti_item_xmlv2p1">
|
19
|
+
<metadata>
|
20
|
+
<imsqti:qtiMetadata xmlns:imsqti="http://www.imsglobal.org/xsd/imsqti_v2p1">
|
21
|
+
<imsqti:itemTemplate>false</imsqti:itemTemplate>
|
22
|
+
<imsqti:composite>false</imsqti:composite>
|
23
|
+
<imsqti:interactionType>extendedTextInteraction</imsqti:interactionType>
|
24
|
+
<imsqti:feedbackType>none</imsqti:feedbackType>
|
25
|
+
</imsqti:qtiMetadata>
|
26
|
+
</metadata>
|
27
|
+
<file href="1009/question4928.xml"/>
|
28
|
+
<file href="1009/Resources/Ixia.gif"/>
|
29
|
+
<file href="1009/Resources/aperture.png"/>
|
30
|
+
</resource>
|
31
|
+
<resource href="1009/question4900.xml" identifier="1785:4900" type="imsqti_item_xmlv2p1">
|
32
|
+
<metadata>
|
33
|
+
<imsqti:qtiMetadata xmlns:imsqti="http://www.imsglobal.org/xsd/imsqti_v2p1">
|
34
|
+
<imsqti:itemTemplate>false</imsqti:itemTemplate>
|
35
|
+
<imsqti:composite>false</imsqti:composite>
|
36
|
+
<imsqti:interactionType>choiceInteraction</imsqti:interactionType>
|
37
|
+
<imsqti:feedbackType>none</imsqti:feedbackType>
|
38
|
+
</imsqti:qtiMetadata>
|
39
|
+
</metadata>
|
40
|
+
<file href="1009/question4900.xml"/>
|
41
|
+
<file href="1009/Resources/512634641600_00_93874928374.jpg"/>
|
42
|
+
<file href="1009/Resources/fmath-equation-9666DCA9-6656-C4BA-4E2D-63AA5B5954C1.png"/>
|
43
|
+
</resource>
|
44
|
+
<resource href="1009/question4961.xml" identifier="1785:4961" type="imsqti_item_xmlv2p1">
|
45
|
+
<metadata>
|
46
|
+
<imsqti:qtiMetadata xmlns:imsqti="http://www.imsglobal.org/xsd/imsqti_v2p1">
|
47
|
+
<imsqti:itemTemplate>false</imsqti:itemTemplate>
|
48
|
+
<imsqti:composite>false</imsqti:composite>
|
49
|
+
<imsqti:interactionType>choiceInteraction</imsqti:interactionType>
|
50
|
+
<imsqti:feedbackType>none</imsqti:feedbackType>
|
51
|
+
</imsqti:qtiMetadata>
|
52
|
+
</metadata>
|
53
|
+
<file href="1009/question4961.xml"/>
|
54
|
+
</resource>
|
55
|
+
<resource href="1009/question4962.xml" identifier="1785:4962" type="imsqti_item_xmlv2p1">
|
56
|
+
<metadata>
|
57
|
+
<imsqti:qtiMetadata xmlns:imsqti="http://www.imsglobal.org/xsd/imsqti_v2p1">
|
58
|
+
<imsqti:itemTemplate>false</imsqti:itemTemplate>
|
59
|
+
<imsqti:composite>false</imsqti:composite>
|
60
|
+
<imsqti:interactionType>choiceInteraction</imsqti:interactionType>
|
61
|
+
<imsqti:feedbackType>none</imsqti:feedbackType>
|
62
|
+
</imsqti:qtiMetadata>
|
63
|
+
</metadata>
|
64
|
+
<file href="1009/question4962.xml"/>
|
65
|
+
<file href="1009/Resources/waterfall_desktop_background-1440x900.jpg"/>
|
66
|
+
</resource>
|
67
|
+
<resource href="1009/question4967.xml" identifier="1788:4967" type="imsqti_item_xmlv2p1">
|
68
|
+
<metadata>
|
69
|
+
<imsqti:qtiMetadata xmlns:imsqti="http://www.imsglobal.org/xsd/imsqti_v2p1">
|
70
|
+
<imsqti:itemTemplate>false</imsqti:itemTemplate>
|
71
|
+
<imsqti:composite>false</imsqti:composite>
|
72
|
+
<imsqti:interactionType>matchInteraction</imsqti:interactionType>
|
73
|
+
<imsqti:feedbackType>none</imsqti:feedbackType>
|
74
|
+
</imsqti:qtiMetadata>
|
75
|
+
</metadata>
|
76
|
+
<file href="1009/question4967.xml"/>
|
77
|
+
</resource>
|
78
|
+
<resource href="1009/question4965.xml" identifier="1788:4965" type="imsqti_item_xmlv2p1">
|
79
|
+
<metadata>
|
80
|
+
<imsmd:lom xmlns:imsmd="http://www.imsglobal.org/xsd/imsmd_v1p2">
|
81
|
+
<imsmd:general>
|
82
|
+
<imsmd:identifier>survey</imsmd:identifier>
|
83
|
+
</imsmd:general>
|
84
|
+
</imsmd:lom>
|
85
|
+
<imsqti:qtiMetadata xmlns:imsqti="http://www.imsglobal.org/xsd/imsqti_v2p1">
|
86
|
+
<imsqti:itemTemplate>false</imsqti:itemTemplate>
|
87
|
+
<imsqti:composite>false</imsqti:composite>
|
88
|
+
<imsqti:interactionType>choiceInteraction</imsqti:interactionType>
|
89
|
+
<imsqti:feedbackType>none</imsqti:feedbackType>
|
90
|
+
</imsqti:qtiMetadata>
|
91
|
+
</metadata>
|
92
|
+
<file href="1009/question4965.xml"/>
|
93
|
+
</resource>
|
94
|
+
<resource href="1009/question4966.xml" identifier="1788:4966" type="imsqti_item_xmlv2p1">
|
95
|
+
<metadata>
|
96
|
+
<imsqti:qtiMetadata xmlns:imsqti="http://www.imsglobal.org/xsd/imsqti_v2p1">
|
97
|
+
<imsqti:itemTemplate>false</imsqti:itemTemplate>
|
98
|
+
<imsqti:composite>false</imsqti:composite>
|
99
|
+
<imsqti:interactionType>textEntryInteraction</imsqti:interactionType>
|
100
|
+
<imsqti:feedbackType>none</imsqti:feedbackType>
|
101
|
+
</imsqti:qtiMetadata>
|
102
|
+
</metadata>
|
103
|
+
<file href="1009/question4966.xml"/>
|
104
|
+
</resource>
|
105
|
+
<resource href="1009/assessment1.xml" identifier="Resource1" type="imsqti_test_xmlv2p1">
|
106
|
+
<metadata>
|
107
|
+
<imsmd:lom xmlns:imsmd="http://www.imsglobal.org/xsd/imsmd_v1p2">
|
108
|
+
<imsmd:general>
|
109
|
+
<imsmd:identifier>assignment</imsmd:identifier>
|
110
|
+
<imsmd:title>
|
111
|
+
<imsmd:langstring>Assignment test? Worth Points</imsmd:langstring>
|
112
|
+
</imsmd:title>
|
113
|
+
</imsmd:general>
|
114
|
+
</imsmd:lom>
|
115
|
+
</metadata>
|
116
|
+
<file href="1009/assessment1.xml"/>
|
117
|
+
<dependency identifierref="1788:4928"/>
|
118
|
+
<dependency identifierref="1785:4900"/>
|
119
|
+
<dependency identifierref="1785:4961"/>
|
120
|
+
<dependency identifierref="1785:4962"/>
|
121
|
+
<dependency identifierref="1788:4967"/>
|
122
|
+
<dependency identifierref="1788:4965"/>
|
123
|
+
<dependency identifierref="1788:4966"/>
|
124
|
+
</resource>
|
125
|
+
<resource identifier="POOL1788" title="Assignment test? Worth Points"/>
|
126
|
+
<resource identifier="POOL1785" title="Question Pool 1"/>
|
127
|
+
</resources>
|
128
|
+
</manifest>
|