class Object

Constants

COMMON_SETTINGS
FIELD_SETTINGS
GROUP
GROUP_MAP

group for each cardtype: { “RichText => ”Content“, ”Layout“ => ”Admin“, … }

SETTING_OPTIONS

Public Class Methods

member_names() click to toggle source

require “json”

# File set/type/setting.rb, line 3
def self.member_names
  @@member_names ||= Card.search(
    { type_id: SettingID, return: "key" },
    "all setting cards"
  ).each_with_object({}) do |card_key, hash|
    hash[card_key] = true
  end
end

Public Instance Methods

all_user_ids_with_rule_for(setting_code) click to toggle source
# File set/type/set.rb, line 57
def all_user_ids_with_rule_for setting_code
  Card::Rule.all_user_ids_with_rule_for self, setting_code
end
anchor() click to toggle source
# File set/type/set.rb, line 7
def anchor
  Card[anchor_name]
end
anchor_name() click to toggle source
# File set/type/set.rb, line 3
def anchor_name
  name.left_name
end
bar_rule_list(settings) click to toggle source
# File set/type/set/html_views/rule_lists.rb, line 26
def bar_rule_list settings
  list_items =
    settings.map { |setting| rule_list_item setting, :bar, hide: :full_name }
  list_items.join("\n").html_safe
end
bar_title() click to toggle source
Calls superclass method
# File set/rule/bar_view.rb, line 62
def bar_title
  return super() if voo.show? :full_name

  linking_to_existing_rule { card.rule_setting_title }
end
bridge_option_list(title) { || ... } click to toggle source
# File set/rule/rule_form/set_selection.rb, line 19
def bridge_option_list title
  index = -1
  formgroup title, input: "set", class: "col-xs-6", help: false do
    yield.inject("") do |res, radio|
      index += 1
      # TODO
      if false # index.in? [2,3]
        wrap_with(:li, radio, class: "radio") + res
      else
        wrap_with :ul do
          wrap_with(:li, (radio + res), class: "radio")
        end
      end
    end
  end
bridge_rule_set_formgroup() click to toggle source
# File set/rule/rule_form/set_selection.rb, line 8
def bridge_rule_set_formgroup
  tag = @rule_context.rule_user_setting_name
  narrower = []

  bridge_option_list "Set" do
    rule_set_options.map do |set_name, state|
      RuleSetRadio.new(self, set_name, tag, state).html narrower
    end
  end
end
bridge_rule_set_selection() click to toggle source
# File set/rule/rule_form/set_selection.rb, line 2
def bridge_rule_set_selection
  wrap_with :div, class: "set-list" do
    bridge_rule_set_formgroup
  end
end
broader_sets() click to toggle source
# File set/type/set.rb, line 84
def broader_sets
  prototype.set_names[1..-1]
end
category_setting_list(cat) click to toggle source
# File set/type/set/setting_lists.rb, line 29
def category_setting_list cat
  case cat
  when :all, :all_rules
    card.visible_setting_codenames.sort
  when :recent, :recent_rules
    recent_settings
  when :common, :common_rules
    card.visible_setting_codenames & COMMON_SETTINGS
  when :field_related, :field_related_rules
    field_related_settings
  when :nest_editor_field_related
    nest_editor_field_related_settings
  end
end
count() click to toggle source
# File set/type/setting.rb, line 21
def count
  Card.search left: { type: SetID }, right: id, limit: 0, return: :count
end
current_rule() click to toggle source
# File set/rule/editor.rb, line 49
def current_rule
  if params[:assign]
    card
  elsif (existing = find_existing_rule_card)
    existing
  else
    card
  end
end
current_rule_form(success_view: :overlay_rule, form_type: :overlay) click to toggle source
# File set/rule/rule_form.rb, line 21
def current_rule_form success_view: :overlay_rule, form_type: :overlay
  current_rule_format = subformat current_rule
  current_rule_format.rule_form success_view, card, form_type
end
current_set_key() click to toggle source
# File set/rule/editor.rb, line 92
def current_set_key
  card.new_card? ? Card.quick_fetch(:all).name.key : card.rule_set_key
end
custom_types() click to toggle source
# File set/self/cardtype.rb, line 32
def custom_types
  custom_types = []

  Card.search(type_id: Card::CardtypeID, return: "name").each do |name|
    next if ::Card::Set::Self::Cardtype::GROUP_MAP[name]

    custom_types << name
  end
  custom_types
end
delete_confirm(fallback_set) click to toggle source
# File set/rule/rule_form/buttons.rb, line 32
def delete_confirm fallback_set
  setting = card.rule_setting_name

  if fallback_set && (fallback_set_card = Card.fetch(fallback_set))
    "Deleting will revert to #{setting} rule for #{fallback_set_card.label}"
  else
    "Are you sure you want to delete the #{setting} rule for #{rule_set_description}?"
  end
end
edit_rule_buttons() click to toggle source
# File set/rule/rule_form/buttons.rb, line 2
def edit_rule_buttons
  wrap_with(:div, class: "button-area") do
    [
      standard_save_button(class: "_rule-submit-button"),
      standard_save_and_close_button(class: "_rule-submit-button", close: form_type),
      edit_rule_cancel_button,
      edit_rule_delete_button
    ]
  end
end
edit_rule_cancel_button() click to toggle source
# File set/rule/rule_form/buttons.rb, line 13
def edit_rule_cancel_button
  send "#{form_type}_close_button", "Cancel", situation: "secondary", class: "btn-sm"
end
edit_rule_delete_button(args={}) click to toggle source
# File set/rule/rule_form/buttons.rb, line 17
def edit_rule_delete_button args={}
  return if card.new_card?

  delete_opts = {
    confirm: delete_confirm(args[:fallback_set]),
    success: {},
    "data-slotter-mode": "silent-success",
    class: "_close-#{form_type}-on-success"
  }
  delete_opts["data-slot-selector"] = slot_selector if args[:slot_selector]
  wrap_with :span, class: "rule-delete-section" do
    delete_button delete_opts
  end
end
edit_rule_form(success_view, &block) click to toggle source
# File set/rule/rule_form.rb, line 42
def edit_rule_form success_view, &block
  @rule_context ||= card
  @edit_rule_success = edit_rule_success success_view
  action_args = { action: :update, no_mark: true }
  card_form action_args, rule_form_args, &block
end
edit_rule_submit_button() click to toggle source
# File set/rule/rule_form/buttons.rb, line 42
def edit_rule_submit_button
  submit_button class: "_rule-submit-button"
end
edit_rule_success(view="overlay_rule") click to toggle source
# File set/rule/rule_form.rb, line 53
def edit_rule_success view="overlay_rule"
  { mark: @rule_context.name.url_key, view: view }
end
edit_rule_title() click to toggle source
# File set/rule/editor.rb, line 42
def edit_rule_title
  output [
    wrap_with(:h5, setting_title, class: "title font-weight-bold")
    # render_overlay_rule_help
  ]
end
existing_rule_card() click to toggle source
# File set/rule/bar_view.rb, line 5
def existing_rule_card
  @existing_rule_card ||= find_existing_rule_card
end
existing_rule_from_prototype() click to toggle source

self.card is a POTENTIAL rule; it quacks like a rule but may or may not exist. This generates a prototypical member of the POTENTIAL rule's set and returns that member's ACTUAL rule for the POTENTIAL rule's setting

# File set/rule/editor.rb, line 105
def existing_rule_from_prototype
  return unless (setting = card.right)

  card.set_prototype.rule_card setting.codename, user: card.rule_user
end
field_settings() click to toggle source
# File set/type/set/setting_lists.rb, line 16
def field_settings
  %i[default help input_type content_options content_option_view]
end
filter_text() click to toggle source
# File set/type/set/rules_filter.rb, line 28
def filter_text
  wrap_with :span, class: "mx-2 small" do
    "rules that apply to #{_render_set_label.downcase}" # LOCALIZE
  end
end
filtered_rule_list(view, *filter_args) click to toggle source
# File set/type/set/html_views.rb, line 23
def filtered_rule_list view, *filter_args
  [rules_filter(view, *filter_args),
   render(view)]
end
find_existing_rule_card() click to toggle source
# File set/rule/editor.rb, line 98
def find_existing_rule_card
  card.new_card? ? existing_rule_from_prototype : card
end
first_set_option_index(candidates) click to toggle source

the narrowest rule should be the one attached to the set being viewed. So, eg, if you're looking at the '*all plus' set, you shouldn't have the option to create rules based on arbitrary narrower sets, though narrower sets will always apply to whatever prototype we create

# File set/rule/rules.rb, line 69
def first_set_option_index candidates
  new_card? ? 0 : candidates.index { |c| c.to_name.key == rule_set_key }
end
followable?() click to toggle source
# File set/self/recent_settings.rb, line 5
def followable?
  false
end
form_type() click to toggle source
# File set/rule/rule_form.rb, line 17
def form_type
  @form_type || :overlay
end
group_setting_list(group) click to toggle source
# File set/type/set/setting_lists.rb, line 25
def group_setting_list group
  card.visible_settings(group).map(&:codename) if Card::Setting.groups[group]
end
history?() click to toggle source
# File set/self/recent_settings.rb, line 1
def history?
  false
end
inheritable?() click to toggle source
# File set/type/set.rb, line 19
def inheritable?
  junction_only? || (anchor_name&.compound? && self_set?)
end
items_for_export() click to toggle source
# File set/type/setting.rb, line 74
def items_for_export
  Card.search left: { type: SetID }, right: card.id, limit: 0
end
junction_only?() click to toggle source
# File set/type/set.rb, line 32
def junction_only?
  @junction_only.nil? ? (@junction_only = subclass_for_set.junction_only) : @junction_only
end
label() click to toggle source
# File set/type/set.rb, line 36
def label
  klass = subclass_for_set
  klass ? klass.label(anchor_name) : ""
end
left_type_for_nest_editor_set_selection() click to toggle source
Calls superclass method
# File set/rule/editor.rb, line 1
def left_type_for_nest_editor_set_selection
  return super unless is_template?

  case rule_set_pattern_name.card_id
  when TypeID
    rule_set.anchor_name
  when SelfID
    rule_set.anchor.type_name
  else
    super
  end
end
linking_to_existing_rule() { || ... } click to toggle source
# File set/rule/bar_view.rb, line 88
def linking_to_existing_rule
  return yield unless existing_rule_card && voo.show?(:toggle)

  link_to_view bar_title_toggle_view, yield
end
option_list(title, &block) click to toggle source
# File set/rule/rule_form/form_elements.rb, line 35
def option_list title, &block
  formgroup title, input: "set", class: "col-xs-6", help: false do
    wrap_with :ul do
      wrap_each_with(:li, class: "radio", &block)
    end
  end
end
pattern() click to toggle source
# File set/type/set.rb, line 15
def pattern
  tag
end
pattern_name() click to toggle source
# File set/type/set.rb, line 11
def pattern_name
  name.tag_name
end
pill_rule_list(settings) click to toggle source
# File set/type/set/html_views/rule_lists.rb, line 20
def pill_rule_list settings
  list_items =
    settings.map { |setting| rule_list_item setting, :rule_bridge_link }
  bridge_pills list_items
end
prototype() click to toggle source
# File set/type/set.rb, line 88
def prototype
  opts = subclass_for_set.prototype_args anchor_name
  Card.fetch opts[:name], new: opts
end
prototype_default_card() click to toggle source
# File set/right/self.rb, line 1
def prototype_default_card
  left
end
prototype_default_type_id() click to toggle source
# File set/type/set.rb, line 93
def prototype_default_type_id
  prototype_default_card.type_id
end
quick_edit() click to toggle source
# File set/rule/quick_editor.rb, line 10
def quick_edit
  haml :quick_edit
end
quick_edit_rule_list(settings) click to toggle source
# File set/type/set/html_views/rule_lists.rb, line 14
def quick_edit_rule_list settings
  list_tag class: "nav nav-pills flex-column bridge-pills" do
    settings.map { |setting| rule_list_item setting, :quick_edit }
  end
end
quick_editor() click to toggle source
# File set/rule/editor.rb, line 59
def quick_editor
  rule_content_formgroup
end
quick_form() click to toggle source
# File set/rule/quick_editor.rb, line 14
def quick_form
  card_form :update, quick_form_opts do
    quick_editor
  end
end
quick_form_opts() click to toggle source
# File set/rule/quick_editor.rb, line 20
def quick_form_opts
  { "data-slot-selector": ".set-info.card-slot",
    success: { view: :quick_edit_success } }
end
recent_settings() click to toggle source
# File set/type/set/setting_lists.rb, line 53
def recent_settings
  recent_settings = Card[:recent_settings].item_cards.map(&:codename)
  recent_settings.map(&:to_sym) & card.visible_setting_codenames
end
right_set_label() click to toggle source
# File set/all/related_sets.rb, line 23
def right_set_label
  Card::Set::Right.label name
end
right_set_name() click to toggle source
# File set/all/related_sets.rb, line 19
def right_set_name
  Name[name, :right]
end
rule_cache_key_base() click to toggle source
# File set/type/set.rb, line 49
def rule_cache_key_base
  if (l = left) && (r = right)
    "#{l.id}+#{Codename[r.id]}"
  else
    Codename[id].to_s
  end
end
rule_content_formgroup() click to toggle source
# File set/rule/editor.rb, line 88
def rule_content_formgroup
  _render_content_formgroup hide: :conflict_tracker
end
rule_for_set?(set_name) click to toggle source
# File set/rule/rules.rb, line 107
def rule_for_set? set_name
  Card.exists?("#{set_name}+#{rule_user_setting_name}")
end
rule_form(success_view, rule_context, form_type=:overlay) click to toggle source
# File set/rule/rule_form.rb, line 26
def rule_form success_view, rule_context, form_type=:overlay
  validate_form_type form_type

  @rule_context = rule_context
  @form_type = form_type
  @success_view = success_view

  render_rule_form
end
rule_form_args() click to toggle source
# File set/rule/rule_form.rb, line 49
def rule_form_args
  { class: "card-rule-form", "data-slotter-mode": "update-origin" }
end
rule_info() click to toggle source

LOCALIZE

# File set/rule/bar_view.rb, line 69
def rule_info
  return wrap_with(:em, "no existing #{setting_link} rule") unless existing_rule_card

  wrap_with :span,
            "#{rule_setting_link} rule that applies to "\
            "#{rule_set_link existing_rule_card}"
end
rule_list_item(setting, view, opts={}) click to toggle source
# File set/type/set/html_views/rule_lists.rb, line 32
def rule_list_item setting, view, opts={}
  return "" unless show_view? setting

  rule_card = card.fetch setting, new: {}
  nest(rule_card, opts.merge(view: view)).html_safe
end
rule_set() click to toggle source
# File set/rule/rules.rb, line 24
def rule_set
  if preference?
    self[0..-3]
  else
    trunk
  end
end
rule_set_description() click to toggle source
# File set/rule/editor.rb, line 71
def rule_set_description
  card.rule_set.follow_label
end
rule_set_formgroup() click to toggle source
# File set/rule/rule_form/form_elements.rb, line 10
def rule_set_formgroup
  tag = @rule_context.rule_user_setting_name
  narrower = []
  option_list "Set" do
    rule_set_options.map do |set_name, state|
      rule_set_radio_button set_name, tag, state, narrower
    end
  end
end
rule_set_key() click to toggle source
# File set/rule/rules.rb, line 8
def rule_set_key
  rule_set_name.key
end
rule_set_name() click to toggle source
# File set/rule/rules.rb, line 12
def rule_set_name
  if preference?
    name.trunk_name.trunk_name
  else
    name.trunk_name
  end
end
rule_set_options() click to toggle source
# File set/rule/rule_form/set_selection.rb, line 36
def rule_set_options
  @rule_set_options ||= @rule_context.set_options
end
rule_set_pattern_name() click to toggle source
# File set/rule/rules.rb, line 20
def rule_set_pattern_name
  rule_set_name.tag_name
end
rule_set_selection() click to toggle source

DEPRECATED

# File set/rule/rule_form/form_elements.rb, line 4
def rule_set_selection
  wrap_with :div, class: "set-list" do
    [rule_set_formgroup, related_set_formgroup]
  end
end
rule_setting() click to toggle source
# File set/rule/rules.rb, line 32
def rule_setting
  right
end
rule_setting_name() click to toggle source
# File set/rule/rules.rb, line 36
def rule_setting_name
  name.tag
end
rule_setting_title() click to toggle source
# File set/rule/rules.rb, line 44
def rule_setting_title
  rule_setting_name.tr "*", ""
end
rule_short_content() click to toggle source
# File set/rule/bar_view.rb, line 54
def rule_short_content
  return "" unless existing_rule_card

  nest existing_rule_card,
       { view: :one_line_content },
       { set_context: card.name.trunk_name }
end
rule_user() click to toggle source
# File set/rstar/rule_user.rb, line 5
def rule_user
  preference? ? self[-2] : nil
end
rule_user_name() click to toggle source
# File set/rstar/rule_user.rb, line 1
def rule_user_name
  preference? ? name.trunk_name.tag : nil
end
rule_user_setting_name() click to toggle source
# File set/rule/rules.rb, line 48
def rule_user_setting_name
  if preference?
    "#{rule_user_name}+#{rule_setting_name}"
  else
    rule_setting_name
  end
end
rules_filter(view, selected_setting=nil, set_options=nil, path_opts={}) click to toggle source
# File set/type/set/rules_filter.rb, line 2
def rules_filter view, selected_setting=nil, set_options=nil, path_opts={}
  form_tag path(path_opts.merge(view: view)),
           remote: true, method: "get", role: "filter",
           "data-slot-selector": ".card-slot.rule-list",
           class: classy("nodblclick slotter form-inline slim-select2 m-2") do
    output [
      label_tag(:view, icon_tag("filter_list"), class: "mr-2"),
      setting_select(selected_setting),
      set_select(set_options)
    ].flatten
  end
end
rules_for_set_class(set_class) click to toggle source
# File set/type/setting.rb, line 32
def rules_for_set_class set_class
  cql = { left: { type: SetID }, right: id, sort: %w[content name], limit: 0 }
  cql[:left][(set_class.anchorless? ? :id : :right_id)] = set_class.pattern_id
  Card.search cql
end
rules_type_formgroup() click to toggle source
# File set/rule/editor.rb, line 75
def rules_type_formgroup
  return unless card.right.rule_type_editable

  success = @edit_rule_success
  wrap_type_formgroup do
    type_field(
      href: path(mark: success[:id], view: :rule_form, assign: true),
      class: "type-field rule-type-field live-type-field",
      "data-remote" => true
    )
  end
end
selected_set() click to toggle source
# File set/type/set/rules_filter.rb, line 41
def selected_set
  params[:set]
end
self_set?() click to toggle source
# File set/type/set.rb, line 23
def self_set?
  pattern_name == Card::Set::Self.pattern.key
end
self_set_label() click to toggle source
# File set/all/related_sets.rb, line 15
def self_set_label
  Card::Set::Self.label name
end
self_set_name() click to toggle source
# File set/all/related_sets.rb, line 11
def self_set_name
  Name[name, :self]
end
set_classes_with_rules() click to toggle source
# File set/type/setting.rb, line 25
def set_classes_with_rules
  Card.set_patterns.reverse.map do |set_class|
    rules = rules_for_set_class set_class
    [set_class, rules] unless rules.empty?
  end.compact
end
set_info(notify_change=nil) click to toggle source
# File set/rule/quick_editor.rb, line 25
def set_info notify_change=nil
  wrap true, class: "set-info" do
    haml :set_info, notify_change: notify_change
  end
end
set_option_candidates() click to toggle source
# File set/rule/rules.rb, line 83
def set_option_candidates
  candidates = set_prototype.set_names
  first = first_set_option_index candidates
  candidates[first..-1]
end
set_options() click to toggle source

~~~~~~~~~~ determine the set options to which a user can apply the rule.

# File set/rule/rules.rb, line 57
def set_options
  @set_options ||= [].tap do |set_options|
    set_option_candidates.each do |set_name|
      set_options << [set_name, state_of_set(set_name)]
    end
  end
end
set_prototype() click to toggle source
# File set/rule/rules.rb, line 73
def set_prototype
  if preference?
    self[0..-3].prototype
  else
    trunk.prototype
  end
end
set_select(set_options) click to toggle source
# File set/type/set/rules_filter.rb, line 15
def set_select set_options
  return filter_text.html_safe unless set_options

  [content_tag(:span, "rules that apply to set ...", class: "mx-2 small"),
   set_select_tag(set_options)]
end
set_select_options(set_options) click to toggle source
# File set/type/set/rules_filter.rb, line 45
def set_select_options set_options
  options =
    if set_options == :related
      related_set_options
    else
      [[card.label, card.name.url_key]]
    end
  options_for_select(options, selected_set)
end
set_select_tag(set_options=:related) click to toggle source
# File set/type/set/rules_filter.rb, line 34
def set_select_tag set_options=:related
  select_tag(:mark, set_select_options(set_options),
             class: "_submit-on-select form-control _close-rule-overlay-on-select",
             "data-minimum-results-for-search": "Infinity",
             "data-select2-id": "#{unique_id}-#{Time.now.to_i}")
end
setting_codenames_by_group() click to toggle source
# File set/type/set.rb, line 61
def setting_codenames_by_group
  result = {}
  Card::Setting.groups.each do |group, settings|
    visible_settings =
      settings.reject { |s| !s || !s.applies_to_cardtype(prototype.type_id) }
    result[group] = visible_settings.map(&:codename) unless visible_settings.empty?
  end
  result
end
setting_group(default=:common) click to toggle source
# File set/type/set/html_views.rb, line 40
def setting_group default=:common
  voo&.filter&.to_sym || params[:group]&.to_sym || default
end
setting_list(val) click to toggle source

@param val setting category, setting group or single setting

# File set/type/set/setting_lists.rb, line 21
def setting_list val
  category_setting_list(val) || group_setting_list(val) || [val]
end
setting_list_from_params(default=:common) click to toggle source
# File set/type/set/html_views/rule_lists.rb, line 39
def setting_list_from_params default=:common
  setting_list setting_group(default)
end
setting_options() click to toggle source
# File set/type/set/setting_lists.rb, line 10
def setting_options
  [["Categories", SETTING_OPTIONS],
   ["Groups", Card::Setting.groups.keys],
   ["Single rules", card.visible_setting_codenames]]
end
setting_select(selected=nil) click to toggle source
# File set/type/set/rules_filter.rb, line 22
def setting_select selected=nil
  select_tag(:group, grouped_options_for_select(setting_options, selected),
             class: "_submit-on-select form-control",
             "data-select2-id": "#{unique_id}-#{Time.now.to_i}")
end
setting_title() click to toggle source
# File set/rule/editor.rb, line 63
def setting_title
  card.name.tag.tr "*", ""
end
short_help_text() click to toggle source
# File set/rule/editor.rb, line 67
def short_help_text
  "<div class=\"help-text\">#{card.short_help_text}</div>"
end
state_of_existing_set() click to toggle source
# File set/rule/rules.rb, line 99
def state_of_existing_set
  @sets_with_existing_rules == 1 ? :current : :overwritten
end
state_of_nonexisting_set() click to toggle source
# File set/rule/rules.rb, line 103
def state_of_nonexisting_set
  @sets_with_existing_rules.positive? ? :overwritten : :available
end
state_of_set(set_name) click to toggle source
# File set/rule/rules.rb, line 89
def state_of_set set_name
  @sets_with_existing_rules ||= 0
  if rule_for_set? set_name
    @sets_with_existing_rules += 1
    state_of_existing_set
  else
    state_of_nonexisting_set
  end
end
subclass_for_set() click to toggle source
# File set/type/set.rb, line 27
def subclass_for_set
  current_set_pattern_code = pattern.codename
  Card.set_patterns.find { |set| set.pattern_code == current_set_pattern_code }
end
uncapitalized_label() click to toggle source
# File set/type/set.rb, line 41
def uncapitalized_label
  label = label.to_s
  return label unless label[0]

  label[0] = label[0].downcase
  label
end
undo_button() click to toggle source
# File set/rule/quick_editor.rb, line 31
def undo_button
  link_to "undo", method: :post, rel: "nofollow", remote: true,
                  class: "btn btn-secondary ml-2 btn-sm btn-reduced-padding slotter",
                  "data-slot-selector": ".card-slot.quick_edit-view",
                  path: { action: :update,
                          revert_actions: [card.last_action_id],
                          revert_to: :previous }
end
validate_form_type(form_type) click to toggle source
# File set/rule/rule_form.rb, line 36
def validate_form_type form_type
  return if form_type.in? %i[overlay modal]

  raise "invalid rule_form type: #{form_type}; has to be overlay or modal"
end
visible_setting_codenames() click to toggle source
# File set/type/set.rb, line 71
def visible_setting_codenames
  @visible_setting_codenames ||= visible_settings.map(&:codename)
end
visible_settings(group=nil, cardtype_id=nil) click to toggle source
# File set/type/set.rb, line 75
def visible_settings group=nil, cardtype_id=nil
  cardtype_id ||= prototype.type_id
  settings =
    (group && Card::Setting.groups[group]) || Card::Setting.groups.values.flatten.compact
  settings.reject do |setting|
    !setting || !setting.applies_to_cardtype(cardtype_id)
  end
end